2011-12-29 62 views
1

我想在Redis的時間線中存儲事件列表。我正在考慮自1970年以來的排序集,以秒爲單位作爲分數,允許快速查找和範圍搜索。在Redis中存儲事件時間線

問題是我希望每個事件都代表一個對象,並帶有幾個鍵(大約3個),所以我會存儲一組有序的ID - 然後應用程序將根據ID。

所以談話會去是這樣的:

> ZRANGEBYSCORE events start end 
1) "16" 
2) "17" 
> HGETALL events:16 
1) "key1" 
2) "val1" 
... 
> HGETALL events:17 
... 

有沒有更好的方式來組織或做的事情,將避免爲每個結果單獨調用應用程序。一切都可以在redis服務器端完成,以避免這種開銷?這是一個大問題嗎?

PS。我正在使用節點客戶端,但我的問題也適用於其他語言。

回答

2

一個顯而易見的解決方案是按值而不是按引用努力工作,找回它。所以你的zset可以存儲序列化的對象,而不是在這些對象上存儲引用。使用節點,JSON易於使用。

現在,如果您需要保留當前結構(例如,因爲您的某些對象由各種zsets共享),那麼您需要考慮使用rountrips而不是命令。 Redis中昂貴的是往返,而不是O(1)命令本身的執行。

HGETALL不支持可變參數(即只能檢索一個散列對象)。但Redis非常擅長處理流水線命令,由於節點的異步特性,這對於node_redis驅動程序來說尤其容易。因此在你的例子中,你只需要2次往返:第一次執行ZRANGEBYSCORE,第二次執行所有HGETALL命令(即在發出第二次HGETALL命令之前不要等待第一次HGETALL命令的結果)。這將是非常有效的。

隨着當前的Redis版本(2.4),無法消除第二次往返。

+0

我們使用這種確切的方法來做類似的事情。另外,Redis腳本部門應該讓您在單次旅行中完成此操作 – tddmonkey 2011-12-30 10:15:33

+0

將所有這些信息存儲在一個字段中是否存在缺陷?就像在rdbms字段中存儲csv一樣?這僅僅是速度的權衡? – Adam 2011-12-30 13:06:29

+0

當物體很小時沒有真正的缺點。當對象較大,並且想要支持部分更新,或者想要從各種容器共享對象時,存在一個缺點。關於你對csv的評論,所有的數據庫系統都必須序列化行(mysql,postgreSQL,Oracle等)。它們中的大多數支持可變長度數據(帶分隔符或大小前綴)。他們使用的格式是二進制的,優化的,但就複雜性而言,序列化的代價與簡單的csv行沒有什麼不同。 – 2011-12-30 14:24:16

1

你可以字符串化的對象,並將其存儲爲stringwith JSON.stringify(),然後用JSON.parse()