使用Redis進行開發

一、常見應用場景

1.會話存儲

在現代的架構中,通常多個服務器位於一個或多個負載均衡器之後。會話(Session)通常需要存儲在外部存儲系統中。如果有一個服務器宕機,其他的服務器可以從外部存儲中獲取會話並繼續服務。因爲與關係數據庫相比Redis的訪問延遲非常低,所以使用Redis來保存會話數據堪稱是一種完美的會話存儲機制。並且Redis中對鍵過期的支持可以天然地用於會話的超時管理。

2.分析

還可以用於統計分析的場景。例如,如果想要計算某個功能被使用了多少次,或者想要計算某個API被調用的次數,那麼簡單地使用INCR命令增加某功能的被點擊次數或某API的被調用次數的計數器即可;甚至還可以結合Lua腳本限制公開 API 的請求次數(將 API 的最大請求數限制在每個 IP 地址每秒鐘十個之內)。因爲所有的Redis命令都是原子的,所以無需擔心競態。基於諸如哈希、有序集合和HyperLoglog等數據類型,還可以構建其他更高級的計數器或統計數據捕獲系統。

3.排行榜

利用有序集合(Sorted Set),就可以輕鬆地實現一個排行榜。例如:可以爲投票目標創建一個有序集合並將用戶的投票數作爲權重。因此,使用ZREVRANGE命令就能夠按照投票目標的受歡迎程度返回投票目標的列表。同樣的功能也可以在關係數據庫中實現,但是SQL查詢要比Redis查詢慢得多。

4.隊列

利用列表(List)的PUSH/POP命令(阻塞類型)就能實現任務隊列。例如:先使用BLPOP命令從任務列表左端移除並獲取第一個任務(沒有的時候則阻塞了),相當於獲取任務;然後使用RPUSH命令從任務列表右端插入一個新任務,相當於分配任務;此時剛纔排隊獲取任務的客戶端就能第一時間拿到新任務。

5.最新的N個記錄

假設我們想要獲取最近新籤的10個合同,通常採用一個SQL查詢:select top 10 * from contract order by signtime desc

而採用Redis解決則可以先創建一個列表,新籤的合同採用LPUSH命令插入,然後再執行LTRIM命令只保留10個元素。

6.緩存

例如:在查詢關係數據庫之前,我們首先在Redis中查找記錄。如果在Redis中找不到記錄,則查詢關係數據庫並將記錄放到Redis中。在向關係數據庫寫入時,我們也同時將記錄寫入Redis。爲了限制緩存的大小,可以對緩存中的記錄設置過期時間或應用諸如最近最少使用(LeastRecentlyUsed,LRU)的收回策略。

 

二、使用正確的數據類型

時間-空間的平衡

例如:10000個用戶信息(id,name,sex,age,registertime)

1.首先存儲爲字符串類型的鍵值對,內存消耗4.04M;

2.改爲哈希類型,內存消耗2.29M左右,此時節省了約43%((4.04-2.29)/4.04)的內存空間;

3.改爲將一個用戶信息存儲爲一個json字符串,內存消耗2.29M,與哈希類型所消耗內存幾乎相同(鍵的數量並沒有減少);

4.使用Lua腳本,利用msgpack庫(https://msgpack.org/)序列化原始json字符串,內存消耗2.06M,此時節省了約49%((4.04-2.06)/4.04)的內存空間;

5.

又例如:計數時可以使用集合、位圖或HyperLogLog

官方一些內存優化的案例:https://redis.io/topics/memory-optimization

 

三、使用正確的Redis API

保證性能

1.儘量將數據操作組合在一起來降低往返延時(RTT),採用管道,採用批量處理的API;

2.因爲Redis是單線程的數據存儲服務,所以應該多考慮API的時間複雜度,避免阻塞服務器。

 

四、使用C#連接到Redis

通過VS(Visual Studio 2017)創建一個控制檯應用程序

通過NuGet獲取StackExchange.Redis

簡單示例

使用管道(事務類似)

運行Lua腳本

local id = @key
local data = @arg
local dataSource = cjson.decode(data)

local retJson = redis.call('get', id)
if retJson == false then
	retJson = {}
else
	retJson = cjson.decode(retJson)
end

for k,v in pairs(dataSource) do
	retJson[k] = v
end
redis.call('set', id, cjson.encode(retJson))
return redis.call('get', id)


五、使用Python連接到Redis

Python(https://www.python.org/),我此時使用的是Python3.7.1

通過PyPI安裝redis-py:執行命令pip install redis

通過VS(Visual Studio 2017)創建一個Python應用程序

簡單示例

示例程序輸出結果如下:

 

使用管道

輸出結果將顯示對應響應的列表

 

運行Lua腳本

local id = KEYS[1]
local data = ARGV[1]
local dataSource = cjson.decode(data)

local retJson = redis.call('get', id)
if retJson == false then
	retJson = {}
else
	retJson = cjson.decode(retJson)
end

for k,v in pairs(dataSource) do
	retJson[k] = v
end
redis.call('set', id, cjson.encode(retJson))
return redis.call('get', id)

執行結果輸出的是更新後的json

 

六、使用Redis編寫MapReduce作業

 

七、使用Redis編寫Spark作業

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章