diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index 3f15f43..6ca5f3d 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Cache;
 
+use Drupal\Component\Utility\Crypt;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\SchemaObjectExistsException;
 
@@ -62,6 +63,10 @@ public function get($cid, $allow_invalid = FALSE) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::getMultiple().
    */
   public function getMultiple(&$cids, $allow_invalid = FALSE) {
+    $cid_mapping = array();
+    foreach ($cids as $cid) {
+      $cid_mapping[$this->ensureCidLength($cid)] = $cid;
+    }
     // When serving cached pages, the overhead of using ::select() was found
     // to add around 30% overhead to the request. Since $this->bin is a
     // variable, this means the call to ::query() here uses a concatenated
@@ -71,13 +76,15 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) {
     // ::select() is a much smaller proportion of the request.
     $result = array();
     try {
-      $result = $this->connection->query('SELECT cid, data, created, expire, serialized, tags, checksum_invalidations, checksum_deletions FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE cid IN (:cids)', array(':cids' => $cids));
+      $result = $this->connection->query('SELECT cid, data, created, expire, serialized, tags, checksum_invalidations, checksum_deletions FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE cid IN (:cids)', array(':cids' => array_keys($cid_mapping)));
     }
     catch (\Exception $e) {
       // Nothing to do.
     }
     $cache = array();
     foreach ($result as $item) {
+      // Map the cache ID back to the original.
+      $item->cid = $cid_mapping[$item->cid];
       $item = $this->prepareItem($item, $allow_invalid);
       if ($item) {
         $cache[$item->cid] = $item;
@@ -196,7 +203,7 @@ protected function doSet($cid, $data, $expire, $tags) {
     }
 
     $this->connection->merge($this->bin)
-      ->key('cid', $cid)
+      ->key('cid', $this->ensureCidLength($cid))
       ->fields($fields)
       ->execute();
   }
@@ -284,14 +291,14 @@ public function delete($cid) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::deleteMultiple().
    */
   public function deleteMultiple(array $cids) {
+    $cids = array_values(array_map(array($this, 'ensureCidLength'), $cids));
     try {
       // Delete in chunks when a large array is passed.
-      do {
+      foreach (array_chunk($cids, 1000) as $cids_chunk) {
         $this->connection->delete($this->bin)
-          ->condition('cid', array_splice($cids, 0, 1000), 'IN')
+          ->condition('cid', $cids_chunk, 'IN')
           ->execute();
       }
-      while (count($cids));
     }
     catch (\Exception $e) {
       // Create the cache table, which will be empty. This fixes cases during
@@ -357,15 +364,15 @@ public function invalidate($cid) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::invalideMultiple().
    */
   public function invalidateMultiple(array $cids) {
+    $cids = array_values(array_map(array($this, 'ensureCidLength'), $cids));
     try {
       // Update in chunks when a large array is passed.
-      do {
+      foreach (array_chunk($cids, 1000) as $cids_chunk) {
         $this->connection->update($this->bin)
           ->fields(array('expire' => REQUEST_TIME - 1))
-          ->condition('cid', array_splice($cids, 0, 1000), 'IN')
+          ->condition('cid', $cids_chunk, 'IN')
           ->execute();
       }
-      while (count($cids));
     }
     catch (\Exception $e) {
       $this->catchException($e);
@@ -549,6 +556,26 @@ protected function catchException(\Exception $e, $table_name = NULL) {
   }
 
   /**
+   * Ensures that cache IDs are valid.
+   *
+   * @param string $cid
+   *   The passed in cache ID.
+   *
+   * @return string
+   *   A cache ID that is at most 255 characters long.
+   */
+  protected function ensureCidLength($cid) {
+    // Nothing to do if the ID length is 255 characters or less.
+    if (strlen($cid) <= 255) {
+      return $cid;
+    }
+    // Return a string that uses as much as possible of the original cache ID
+    // with the hash appended.
+    $hash = Crypt::hashBase64($cid);
+    return substr($cid, 0, 255 - strlen($hash)) . $hash;
+  }
+
+  /**
    * Defines the schema for the cache bin and cache_tags table.
    */
   public function schemaDefinition() {
diff --git a/core/lib/Drupal/Core/Cache/PhpBackend.php b/core/lib/Drupal/Core/Cache/PhpBackend.php
index 81f5876..73153c9 100644
--- a/core/lib/Drupal/Core/Cache/PhpBackend.php
+++ b/core/lib/Drupal/Core/Cache/PhpBackend.php
@@ -8,7 +8,7 @@
 namespace Drupal\Core\Cache;
 
 use Drupal\Core\PhpStorage\PhpStorageFactory;
-use Drupal\Component\Utility\Variable;
+use Drupal\Component\Utility\Crypt;
 
 /**
  * Defines a PHP cache implementation.
@@ -49,7 +49,23 @@ public function __construct($bin) {
    * {@inheritdoc}
    */
   public function get($cid, $allow_invalid = FALSE) {
-    if ($file = $this->storage()->getFullPath($cid)) {
+    return $this->getByHash(Crypt::hashBase64($cid), $allow_invalid);
+  }
+
+  /**
+   * Fetch a cache item using a hashed cache ID.
+   *
+   * @param string $cidhash
+   *   The hashed version of the original cache ID after applying
+   *   Crypt::hashBase64().
+   * @param bool $allow_invalid
+   *   (optional) If TRUE, a cache item may be returned even if it is expired or
+   *   has been invalidated.
+   *
+   * @return bool|mixed
+   */
+  protected function getByHash($cidhash, $allow_invalid = FALSE) {
+    if ($file = $this->storage()->getFullPath($cidhash)) {
       $cache = @include $file;
     }
     if (isset($cache)) {
@@ -125,14 +141,14 @@ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array
       'expire' => $expire,
     );
     $item->tags = $this->flattenTags($tags);
-    $this->writeItem($cid, $item);
+    $this->writeItem(Crypt::hashBase64($cid), $item);
   }
 
   /**
    * {@inheritdoc}
    */
   public function delete($cid) {
-    $this->storage()->delete($cid);
+    $this->storage()->delete(Crypt::hashBase64($cid));
   }
 
   /**
@@ -149,10 +165,10 @@ public function deleteMultiple(array $cids) {
    */
   public function deleteTags(array $tags) {
     $flat_tags = $this->flattenTags($tags);
-    foreach ($this->storage()->listAll() as $cid) {
-      $item = $this->get($cid);
+    foreach ($this->storage()->listAll() as $cidhash) {
+      $item = $this->getByHash($cidhash);
       if (is_object($item) && array_intersect($flat_tags, $item->tags)) {
-        $this->delete($cid);
+        $this->delete($item->cid);
       }
     }
   }
@@ -168,9 +184,20 @@ public function deleteAll() {
    * {@inheritdoc}
    */
   public function invalidate($cid) {
-    if ($item = $this->get($cid)) {
+    $this->invalidatebyHash(Crypt::hashBase64($cid));
+  }
+
+  /**
+   * Invalidate one cache item.
+   *
+   * @param string $cidhash
+   *   The hashed version of the original cache ID after applying
+   *   Crypt::hashBase64().
+   */
+  protected function invalidatebyHash($cidhash) {
+    if ($item = $this->getByHash($cidhash)) {
       $item->expire = REQUEST_TIME - 1;
-      $this->writeItem($cid, $item);
+      $this->writeItem($cidhash, $item);
     }
   }
 
@@ -188,10 +215,10 @@ public function invalidateMultiple(array $cids) {
    */
   public function invalidateTags(array $tags) {
     $flat_tags = $this->flattenTags($tags);
-    foreach ($this->storage()->listAll() as $cid) {
-      $item = $this->get($cid);
+    foreach ($this->storage()->listAll() as $cidhash) {
+      $item = $this->getByHash($cidhash);
       if ($item && array_intersect($flat_tags, $item->tags)) {
-        $this->invalidate($cid);
+        $this->invalidate($item->cid);
       }
     }
   }
@@ -200,7 +227,9 @@ public function invalidateTags(array $tags) {
    * {@inheritdoc}
    */
   public function invalidateAll() {
-    $this->invalidateMultiple($this->storage()->listAll());
+    foreach($this->storage()->listAll() as $cidhash) {
+      $this->invalidatebyHash($cidhash);
+    }
   }
 
   /**
@@ -248,20 +277,21 @@ public function removeBin() {
   /**
    * Writes a cache item to PhpStorage.
    *
-   * @param string $cid
-   *   The cache ID of the data to store.
+   * @param string $cidhash
+   *   The hashed version of the original cache ID after applying
+   *   Crypt::hashBase64().
    * @param \stdClass $item
    *   The cache item to store.
    */
-  protected function writeItem($cid, \stdClass $item) {
+  protected function writeItem($cidhash, \stdClass $item) {
     $content = '<?php return unserialize(' . var_export(serialize($item), TRUE) . ');';
-    $this->storage()->save($cid, $content);
+    $this->storage()->save($cidhash, $content);
   }
 
   /**
    * Gets the PHP code storage object to use.
    *
-   * @return \Drupal\Core\PhpStorage\PhpStorageInterface
+   * @return \Drupal\Component\PhpStorage\PhpStorageInterface
    */
   protected function storage() {
     if (!isset($this->storage)) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
index 0a9108c..4d14ca3 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\system\Tests\Cache\GenericCacheBackendUnitTestBase.
+ * Contains \Drupal\system\Tests\Cache\GenericCacheBackendUnitTestBase..
  */
 
 namespace Drupal\system\Tests\Cache;
@@ -187,6 +187,11 @@ public function testSetGet() {
     $cached = $backend->get('test6');
     $this->assert(is_object($cached), "Backend returned an object for cache id test6.");
     $this->assertIdentical($with_variable, $cached->data);
+
+    // Check with a long key.
+    $cid = str_repeat('a', 300);
+    $backend->set($cid, 'test');
+    $this->assertEqual('test', $backend->get($cid)->data);
   }
 
   /**
@@ -210,6 +215,11 @@ public function testDelete() {
 
     $backend->delete('test2');
     $this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion.");
+
+    $long_cid = str_repeat('a', 300);
+    $backend->set($long_cid, 'test');
+    $backend->delete($long_cid);
+    $this->assertIdentical(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion.");
   }
 
   /**
@@ -247,6 +257,7 @@ public function testGetMultiple() {
     $backend = $this->getCacheBackend();
 
     // Set numerous testing keys.
+    $long_cid = str_repeat('a', 300);
     $backend->set('test1', 1);
     $backend->set('test2', 3);
     $backend->set('test3', 5);
@@ -254,6 +265,7 @@ public function testGetMultiple() {
     $backend->set('test5', 11);
     $backend->set('test6', 13);
     $backend->set('test7', 17);
+    $backend->set($long_cid, 300);
 
     // Mismatch order for harder testing.
     $reference = array(
@@ -321,6 +333,12 @@ public function testGetMultiple() {
     $this->assertFalse(in_array('test2', $cids), "Existing cache id test2 is not in cids array.");
     $this->assertFalse(in_array('test7', $cids), "Existing cache id test7 is not in cids array.");
     $this->assertFalse(in_array('test19', $cids), "Added cache id test19 is not in cids array.");
+
+    // Test with a long $cid and non-numeric array key.
+    $cids = array('key:key' => $long_cid);
+    $return = $backend->getMultiple($cids);
+    $this->assertEqual(300, $return[$long_cid]->data);
+    $this->assertTrue(empty($cids));
   }
 
   /**
@@ -400,6 +418,9 @@ public function testDeleteMultiple() {
     // Test if that expected keys do not exist.
     $this->assertIdentical(FALSE, $backend->get('test19'), "Cache id test19 does not exist.");
     $this->assertIdentical(FALSE, $backend->get('test21'), "Cache id test21 does not exist.");
+
+    // Calling deleteMultiple() with an empty array should not cause an error.
+    $backend->deleteMultiple(array());
   }
 
   /**
@@ -508,6 +529,10 @@ function testInvalidate() {
     $cids = $reference;
     $ret = $backend->getMultiple($cids, TRUE);
     $this->assertEqual(count($ret), 4, 'Four items returned.');
+
+    // Calling invalidateMultiple() with an empty array should not cause an
+    // error.
+    $backend->invalidateMultiple(array());
   }
 
   /**
