Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

Thiết kế phím Redis cho ứng dụng chứng khoán thời gian thực

Đề xuất của tôi là lưu trữ min / max / total cho tất cả các khoảng thời gian bạn quan tâm và cập nhật nó cho những khoảng thời gian hiện tại với mọi điểm dữ liệu đến. Để tránh độ trễ mạng khi đọc dữ liệu trước đó để so sánh, bạn có thể thực hiện hoàn toàn bên trong máy chủ Redis bằng cách sử dụng tập lệnh Lua.

Một khóa cho mỗi điểm dữ liệu (hoặc thậm chí tệ hơn, cho mỗi trường điểm dữ liệu) sẽ tiêu tốn quá nhiều bộ nhớ. Để có kết quả tốt nhất, bạn nên nhóm nó thành các danh sách / băm nhỏ (xem http://redis.io/topics/memory-optimization). Redis chỉ cho phép một mức lồng trong cấu trúc dữ liệu của nó:nếu dữ liệu của bạn có nhiều trường và bạn muốn lưu trữ nhiều hơn một mục trên mỗi khóa, bạn cần phải tự mã hóa bằng cách nào đó. May mắn thay, môi trường Redis Lua tiêu chuẩn bao gồm hỗ trợ msgpack, một định dạng giống JSON nhị phân rất hiệu quả. Các mục nhập JSON trong ví dụ của bạn được mã hóa bằng msgpack "nguyên trạng" sẽ dài 52-53 byte. Tôi khuyên bạn nên nhóm theo thời gian để bạn có 100-1000 mục nhập cho mỗi khóa. Giả sử khoảng thời gian một phút phù hợp với yêu cầu này. Sau đó, sơ đồ khóa sẽ như thế này:

YYmmddHHMMSS - một hàm băm từ tid thành các điểm dữ liệu được mã hóa msgpack cho một phút nhất định. 5m:YYmmddHHMM , 1h:YYmmddHH , 1d:YYmmdd - băm dữ liệu cửa sổ chứa min , max , sum các lĩnh vực.

Hãy xem một tập lệnh Lua mẫu sẽ chấp nhận một điểm dữ liệu và cập nhật tất cả các khóa nếu cần. Do cách thức hoạt động của tập lệnh Redis, chúng tôi cần chuyển rõ ràng tên của tất cả các khóa sẽ được tập lệnh truy cập, tức là dữ liệu trực tiếp và cả ba khóa cửa sổ. Redis Lua cũng có sẵn thư viện phân tích cú pháp JSON, vì vậy để đơn giản, hãy giả sử chúng ta chỉ chuyển nó từ điển JSON. Điều đó có nghĩa là chúng tôi phải phân tích cú pháp dữ liệu hai lần:ở phía ứng dụng và phía Redis, nhưng hiệu quả hoạt động của nó không rõ ràng.

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)

Thiết lập này có thể thực hiện hàng nghìn bản cập nhật mỗi giây, không tốn nhiều bộ nhớ và dữ liệu cửa sổ có thể được truy xuất ngay lập tức.

CẬP NHẬT:Về phần bộ nhớ, 50-60 byte mỗi điểm vẫn còn nhiều nếu bạn muốn lưu trữ thêm vài triệu. Với loại dữ liệu này, tôi nghĩ rằng bạn có thể nhận được thấp nhất là 2-3 byte mỗi điểm bằng cách sử dụng định dạng nhị phân tùy chỉnh, mã hóa delta và nén các phần tiếp theo bằng cách sử dụng một cái gì đó như snappy. Nó phụ thuộc vào yêu cầu của bạn, liệu nó có đáng để làm điều này hay không.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Redis dưới dạng cơ sở dữ liệu

  2. Redis xuất bản / đăng ký:xem những kênh nào hiện được đăng ký

  3. Làm cách nào để đặt một cụm redis co giãn làm nô lệ?

  4. blpop dừng xử lý hàng đợi sau một thời gian

  5. triển khai redis đến heroku không thể kết nối