2012-05-29 24 views

Trả lời

36

Memcached không cung cấp chức năng này ra khỏi hộp, do đó bạn phải tự xây dựng nó.

Cách tôi giải quyết vấn đề này là xác định tiền tố (hoặc không gian tên) trong ứng dụng của tôi cho các nhóm khóa. Bất kỳ khóa nào tôi đặt trong memcached đều có tiền tố đó trước nó. Bất cứ khi nào tôi muốn "xóa" các công cụ từ Memcached, tôi chỉ cần thay đổi tiền tố. Và bất cứ khi nào tôi muốn tra cứu một khóa trong Memcached, tôi thêm tiền tố đó vào nó.

Trong trường hợp của bạn, bạn có thể bắt đầu bằng cách đặt tiền tố, ví dụ: MyAppPrefix1, vì vậy, các khóa của bạn sẽ được lưu trữ là MyAppPrefix1::app_333333, MyAppPrefix1::app_444444.

Sau đó khi bạn muốn "xóa" các mục nhập này, hãy đặt ứng dụng của bạn để sử dụng MyAppPrefix2. Sau đó, khi bạn cố gắng lấy chìa khóa từ Memcached được gọi là app_333333, nó sẽ tìm kiếm MyAppPrefix2::app_333333 và sẽ không tìm thấy nó lần đầu tiên xung quanh, như thể nó đã bị xóa.

+1

Và cách bạn xóa các mục cũ? hết hạn thời gian? –

+0

@ AlfonsoFernandez-Ocampo vâng, tại sao không? Memcache sẽ xóa chúng khi cần – yefrem

+0

trông thật xuất sắc, nhưng, Memcached sẽ xóa sau khi hết hạn hoặc khi nó sắp đầy? – kscius

4

Làm thế nào về chức năng này trong php:

function deletekeysbyindex($prefix) { 
    $m = new Memcached(); 
    $m->addServer('localhost', 11211); 
    $keys = $m->getAllKeys(); 
    foreach ($keys as $index => $key) { 
     if (strpos($key,$prefix) !== 0) { 
      unset($keys[$index]); 
     } else { 
      $m->delete($key); 
     } 
    } 
    return $keys; 
} 

Xóa phím bắt đầu với $ tiền tố và trả về một danh sách tất cả các phím loại bỏ. Tôi đã chạy điều này trên 30.000 + phím ngay bây giờ trên một máy chủ được chia sẻ và nó đã được khá nhanh chóng - có lẽ ít hơn một giây.

+2

Điều này không đảm bảo hoạt động. http://php.net/manual/en/memcached.getallkeys.php "Vì memcache không đảm bảo trả lại tất cả các khóa, bạn cũng không thể giả định rằng tất cả các khóa đã được trả lại." –

+2

Cảm ơn bạn đã chỉ ra điều đó @TimMartens. Tôi cho rằng nó tốt như bạn có thể nhận được? Tôi muốn có một chút thông tin thêm về khi nào và tại sao phương thức 'getAllKeys()' có khả năng xuất hiện ngắn ... bạn có thể làm sáng tỏ điều này không? Các tài liệu khá vô ích. – billynoah

0

Chúng tôi không thể thực hiện điều đó chỉ trong một yêu cầu đối với memcache. Chúng tôi chỉ có thể làm điều này:

public function clearByPrefix($prefixes = array()) { 
    $prefixes = array_unique($prefixes); 

    $slabs = $this->memcache->getExtendedStats('slabs'); 
    foreach ($slabs as $serverSlabs) { 
     if ($serverSlabs) { 
      foreach ($serverSlabs as $slabId => $slabMeta) { 
       if (is_int($slabId)) { 
        try { 
         $cacheDump = $this->memcache->getExtendedStats('cachedump', (int) $slabId, 1000); 
        } catch (Exception $e) { 
         continue; 
        } 

        if (is_array($cacheDump)) { 
         foreach ($cacheDump as $dump) { 
          if (is_array($dump)) { 
           foreach ($dump as $key => $value) { 

            $clearFlag = false; 
            // Check key has prefix or not 
            foreach ($prefixes as $prefix) { 
             $clearFlag = $clearFlag || preg_match('/^' . preg_quote($prefix, '/') . '/', $key); 
            } 
            // Clear cache 
            if ($clearFlag) { 
             $this->clear($key); 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 

Và gọi hàm này như sau:

 $prefixes = array(); 

     array_push($prefixes, 'prefix1_'); 
     array_push($prefixes, 'prefix2_'); 
     array_push($prefixes, 'prefix3_'); 

     $this->clearByPrefix($prefixes); 
+0

Ngay cả khi mã của bạn có vẻ dễ hiểu, bạn có thể giải thích nó là gì và tại sao bạn tin rằng giải pháp này giúp người hỏi. Bằng cách này, preg_match khi bạn chỉ có thể gọi strpos, thực sự là một overkill. –

+0

Có lẽ tôi nên thêm ý kiến ​​trong mã của tôi :) Về preg_match, tôi không nghĩ rằng đó là một quá mức cần thiết. Bạn biết đấy, nó chỉ là một điều đơn giản cho trường hợp này. Tôi thậm chí còn có ý định rằng regex sẽ phức tạp hơn trong tương lai. :) Cảm ơn bro bình luận của bạn! –

0

Đây là một hack mà làm việc, mặc dù một chút chậm. Trên máy chủ có 0,6 triệu khóa, mất nửa giây để hoàn thành.

$prefix = 'MyApp::Test'; 
    $len = strlen($prefix); 

    $proc = popen('/usr/local/bin/memdump --servers=localhost', 'r'); 
    while (($key = fgets($proc)) !== false) { 
     if (substr_compare($key, $prefix, 0, $len) === 0) { 
      $memcached->delete(substr($key, 0, -1)); 
     } 
    } 
Các vấn đề liên quan