Redis
 sql >> база данни >  >> NoSQL >> Redis

Ключов дизайн на Redis за приложение в реално време

Моето предложение е да съхранявате min/max/total за всички интервали, които ви интересуват, и да го актуализирате за текущи с всяка пристигаща точка от данни. За да избегнете забавяне на мрежата при четене на предишни данни за сравнение, можете да го направите изцяло в Redis сървър, като използвате Lua скриптове.

Един ключ на точка от данни (или, още по-лошо, на поле за точка от данни) ще изразходва твърде много памет. За най-добри резултати трябва да го групирате в малки списъци/хешове (вижте http://redis.io/topics/memory-optimization). Redis позволява само едно ниво на влагане в своите структури от данни:ако вашите данни имат множество полета и искате да съхранявате повече от един елемент на ключ, трябва по някакъв начин да го кодирате сами. За щастие стандартната среда на Redis Lua включва поддръжка на msgpack, която е много ефективен двоичен формат, подобен на JSON. JSON записите във вашия пример, кодирани с msgpack "както е", ще бъдат дълги 52-53 байта. Предлагам да групирате по време, така че да имате 100-1000 записа на ключ. Да предположим, че интервалът от една минута отговаря на това изискване. Тогава схемата за въвеждане ще бъде следната:

YYmmddHHMMSS — хеш от tid до точки от данни, кодирани от msgpack за дадена минута.5m:YYmmddHHMM , 1h:YYmmddHH , 1d:YYmmdd — хешове на данни на прозореца, които съдържат min , max , sum полета.

Нека разгледаме примерен Lua скрипт, който ще приеме една точка от данни и ще актуализира всички ключове, ако е необходимо. Поради начина, по който работи скриптовете на Redis, трябва изрично да предадем имената на всички ключове, които ще бъдат достъпни от скрипта, т.е. живите данни и трите ключа на прозореца. Redis Lua разполага и с библиотека за разбор на JSON, така че за простота нека приемем, че просто я предадем JSON речник. Това означава, че трябва да анализираме данните два пъти:от страната на приложението и от страната на Redis, но ефектите на производителността от тях не са ясни.

local function update_window(winkey, price, amount)
    local windata = redis.call('HGETALL', winkey)
    if price > tonumber(windata.max or 0) then
        redis.call('HSET', winkey, 'max', price)
    end
    if price < tonumber(windata.min or 1e12) then
        redis.call('HSET', winkey, 'min', price)
    end
    redis.call('HSET', winkey, 'sum', (windata.sum or 0) + amount)
end

local currkey, fiveminkey, hourkey, daykey = unpack(KEYS)
local data = cjson.decode(ARGV[1])
local packed = cmsgpack.pack(data)
local tid = data.tid
redis.call('HSET', currkey, tid, packed)
local price = tonumber(data.price)
local amount = tonumber(data.amount)
update_window(fiveminkey, price, amount)
update_window(hourkey, price, amount)
update_window(daykey, price, amount)

Тази настройка може да прави хиляди актуализации в секунда, не е много гладна за памет, а данните от прозореца могат да бъдат извлечени незабавно.

АКТУАЛИЗАЦИЯ:Относно паметта, 50-60 байта на точка са все още много, ако искате да съхранявате още няколко милиона. С този вид данни мисля, че можете да получите до 2-3 байта на точка, като използвате персонализиран двоичен формат, делта кодиране и последващо компресиране на парчета с помощта на нещо като snappy. Зависи от вашите изисквания, дали си струва да направите това.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. проблеми при задаване на бекенда на задачи celery в Python

  2. Деактивирайте прозрачните огромни страници от Kubernetes

  3. Pizza Tribes – стратегическа игра в реално време, базирана на мултиплейър

  4. LogicException:Моля, уверете се, че разширението PHP Redis е инсталирано и активирано

  5. Redis Python - как да изтриете всички ключове според определен модел В python, без итерация на python