Anahtar / değer depolamadaki öğelerin süresi dolma algoritması nedir?


10

Mevcut anahtar / değer depolarının öğeler için "son kullanma tarihi" ni nasıl uyguladığını düşünüyordum. Şu anda aklımda bunun için 2 varyant var:

  1. hiçbir şey yapmazlar (süresi dolmuş verileri saklarlar) ve yalnızca ne zaman yaptığınızı kontrol ederler, örneğin, bir anahtarla GET. Buradaki sorun, bellekte sınırlıysanız, süresi dolmuş öğelerin silinmemesidir.
  2. "süresi dolmak üzere" alabilmek için ek veri yapılarını korurlar. Bunun gibi bir şeyle yapılabileceğini görüyorum:

    storage_data = dict(key -> [value, expire_timestamp])
    expire_tree = SomeBinaryLikeTree(expire_timestamp -> [keys])
    

Yanıtlar:


6

Önbellekteki süresi dolmuş girişleri silme sorunu , referans sayımının tümüyle eksi olarak , çöp toplama işlemine eşdeğerdir .

Nasza-Klasa'daki insanlar Memcache için O (1) algoritmasını şu şekilde önerdiler:

Birçok insanın bir sebepten dolayı O (1) 'de süresi dolmuş girişlerin serbest bırakılmasının mümkün olamayacağına, hatta Omega (N) operasyonları gerektirdiğine inanılıyor gibi görünüyor. Bir yığın veya başka öncelik kuyruğu veri yapıları kullanmak size açıkça O (log N) verebilir, ancak aşağıdaki yama O (1) 'i hedefler. Bu, her saniye için bir kovaya sahip olmak ve her girişi, son kullanma zamanına bakarak uygun bir kovaya koymak suretiyle elde edilir. Sonra her saniyede bir sonraki kovadaki öğeleri serbest bırakıyoruz. Bu açıkça O (1) amortisman süresidir, ancak aynı anda süresi dolan çok sayıda öğeniz olabilir, bu nedenle yama bir istek başına gerçekleştirmek istediğiniz işlem sayısı için sabit bir sınır sunar, çöp toplama işlemini daha düzgün hale getirmek için.

Ekli kodla birlikte tüm teklife bakın .


Teşekkürler. Ben de "kova" çözüm üzerinde düşündüm. Ayrıca "kovada çok fazla öğe" ile ilgili bir sorun yok, çünkü algoritma ile gidebilirsiniz "son kez almadığınız kovaları alın ve işiniz bittiğinde geri dönün".
Kostiantyn Rybnikov

@k_bx: bu yüzden çift bağlantılı liste öneriyorlar, böylece önceki bölümlere geri dönebilirsiniz.
vartec

Kovalar saniyeler gibi bir şeyse, bağlantılı listelere ihtiyacınız yoktur. Önceki
konuya geçmek için

@k_bx: anahtarı ne kadar azaltmak? bir saniye? önceki tamamen boşaltılmamış kova 5 dakika önce olsaydı? 1s adım adım 300 kat azalır mı?
vartec

İlk sunucu başlangıcında, current_expire_bucket adlı değişkeni bir değere başlatırsınız. Ardından, current_expire_bucket'ten başlayarak geçerli saniyeyi bitiren temizleme işlemini çalıştırın. Temizleme sona erdikten sonra küçük bir süre uyursunuz. Sunucu durursa, aynı "sona erme grubunu" tekrar geçersiniz, evet, ancak yalnızca sunucu duraklarında gerçekleşmelidir.
Kostiantyn Rybnikov

7

Anahtar / değer depolama alanının, hangisinin süresi dolabileceğini bulmak için tüm kv çiftleri üzerinde yineleme yapmak için çok büyük olduğunu varsayıyorum. Ayrıca, her bir okuma erişiminin süre sonu zaman damgasını yenilediğini varsayıyorum, bu nedenle yalnızca bir süredir erişilmeyen öğelerin süresi dolmuş.

Zorluk, süresi dolan tüm kayıtları etkin bir şekilde bulmaktır (temizleme zamanı geldiğinde), ancak her okuma erişimindeki süre sonu zaman damgasını da verimli bir şekilde yenilemektir (bu nedenle, süre sonu için kullanılan yapıdaki anahtarı bulmalıyız).

Benim önerim: expiry_timestamps grubunu gruplara yerleştirmek; örneğin, öğeler 8 saat yaşarsa, saatte bir kova yapın. Bu kovalar bağlantılı bir listede tutulur; son kullanma tarihi geldiğinde, ilk kova boşaltılır ve liste azaltılır. Kova sayısı kullanım ömrü / temizleme aralığıdır. Her bir kova, süresi dolması gereken tüm anahtarların bir karma kümesini içerir. Bir hashsetteki tüm tuşlar üzerinde yineleme yeterince etkilidir.

Okuma erişimi sırasında, program, anahtarın hangi grupta olduğunu ve şimdi hangi gruba ait olduğunu kontrol eder. Çoğu durumda, aynı kovadır, bu nedenle başka bir işlem yapılması gerekmez. Aksi takdirde, anahtarı eski kovadan çıkarın (bir karma kümesinden çıkarmak etkilidir) ve yeni kovaya takın.

   +--------------+   +--------------+   +--------------+
-->+ Expiry 08:00 +-->+ Expiry 09:00 +-->+ Expiry 10:00 +
   | KeySet       |   | KeySet       |   | KeySet       |
   +--------------+   +--------------+   +--------------+
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.