Belirli bir cevap kümesine bazı eklemeler:
Her şeyden önce, Redis hash'ı verimli bir şekilde kullanacaksanız, bir anahtar sayısı maksimum sayı ve maksimum boyut değerlerini bilmelisiniz - aksi takdirde hash-max-ziplist-değerini veya hash-max-ziplist-girişlerini çıkarırlarsa Redis bunu pratik olarak dönüştürür normal anahtar / değer çiftleri bir başlık altında. (bkz. hash-max-ziplist-value, hash-max-ziplist-girişleri) Ve karma seçeneklerden bir başlık altında kırmak GERÇEKTEN KÖTÜDİR, çünkü Redis içindeki her normal anahtar / değer çifti çift başına +90 bayt kullanır.
Bu, ikinci seçenekle başlarsanız ve yanlışlıkla max-hash-ziplist değerinden koparsanız, her kullanıcı modelinde sahip olduğunuz her bir ATTRIBUTE başına +90 bayt elde edeceğiniz anlamına gelir! (aslında +90 değil + +70 aşağıdaki konsol çıktısına bakın)
# you need me-redis and awesome-print gems to run exact code
redis = Redis.include(MeRedis).configure( hash_max_ziplist_value: 64, hash_max_ziplist_entries: 512 ).new
=> #<Redis client v4.0.1 for redis://127.0.0.1:6379/0>
> redis.flushdb
=> "OK"
> ap redis.info(:memory)
{
"used_memory" => "529512",
**"used_memory_human" => "517.10K"**,
....
}
=> nil
# me_set( 't:i' ... ) same as hset( 't:i/512', i % 512 ... )
# txt is some english fictionary book around 56K length,
# so we just take some random 63-symbols string from it
> redis.pipelined{ 10000.times{ |i| redis.me_set( "t:#{i}", txt[rand(50000), 63] ) } }; :done
=> :done
> ap redis.info(:memory)
{
"used_memory" => "1251944",
**"used_memory_human" => "1.19M"**, # ~ 72b per key/value
.....
}
> redis.flushdb
=> "OK"
# setting **only one value** +1 byte per hash of 512 values equal to set them all +1 byte
> redis.pipelined{ 10000.times{ |i| redis.me_set( "t:#{i}", txt[rand(50000), i % 512 == 0 ? 65 : 63] ) } }; :done
> ap redis.info(:memory)
{
"used_memory" => "1876064",
"used_memory_human" => "1.79M", # ~ 134 bytes per pair
....
}
redis.pipelined{ 10000.times{ |i| redis.set( "t:#{i}", txt[rand(50000), 65] ) } };
ap redis.info(:memory)
{
"used_memory" => "2262312",
"used_memory_human" => "2.16M", #~155 byte per pair i.e. +90 bytes
....
}
TheHippo cevabı için Birinci seçenek hakkındaki yorumlar yanıltıcıdır:
Tüm alanlara veya birden fazla get / set işlemine ihtiyacınız varsa hgetall / hmset / hmget kurtarmaya.
BMiner cevabı için.
Üçüncü seçenek aslında gerçekten eğlencelidir, max (id) <has-max-ziplist-değeri olan veri kümesi için bu çözümün O (N) karmaşıklığı vardır, çünkü sürpriz, Reddis küçük karmaları dizi / anahtar / değer dizisi kabı olarak depolar nesneleri!
Ancak birçok kez karma sadece birkaç alan içerir. Karmalar küçük olduğunda, bunun yerine uzunluk (ön) anahtar değeri çiftlerine sahip doğrusal bir dizi gibi O (N) veri yapısında kodlayabiliriz. Bunu sadece N küçükken yaptığımız için, HGET ve HSET komutları için amortisman süresi hala O (1): içerdiği öğe sayısı çok fazla artar artmaz, gerçek bir karma tablosuna dönüştürülecektir.
Ancak endişelenmemelisiniz, hash-max-ziplist girişlerini çok hızlı kıracaksınız ve işte şimdi 1 numaralı çözümde bulunuyorsunuz.
İkinci seçenek büyük olasılıkla bir başlık altında dördüncü çözüme gidecektir, çünkü soru belirttiği gibi:
Bir karma kullanırsam değer uzunluğunun tahmin edilemeyeceğini unutmayın. Bunların hepsi yukarıdaki biyo örneği gibi kısa değil.
Ve daha önce de söylediğin gibi: dördüncü çözüm, her özellik için en pahalı +70 bayttır.
Benim önerim böyle bir veri kümesini nasıl optimize edeceğim:
İki seçeneğiniz var:
İlk çözüm için kullandığınızdan daha fazla kullanıcı özniteliğinin maksimum boyutunu garanti edemiyorsanız ve bellek sorunu yeniden depolanmadan önce json'u sıkıştırmaktan daha önemliyse.
Tüm niteliklerin maksimum boyutunu zorlayabiliyorsanız. Daha sonra hash-max-ziplist-girdilerini / değerini ayarlayabilir ve karmaları kullanıcı temsili başına bir karma olarak VEYA bir Redis kılavuzunun bu konusundan karma bellek optimizasyonu olarak kullanabilirsiniz: https://redis.io/topics/memory-optimization ve kullanıcıyı json dizesi olarak saklar. Her iki şekilde de uzun kullanıcı özelliklerini sıkıştırabilirsiniz.