極鏈科技Video++:劉偉
整理:包包
redis是一種提供多種數(shù)據(jù)類型的開源key-value存儲系統(tǒng),通常將數(shù)據(jù)全部存儲在內(nèi)存中。
redis是目前最受歡迎的key-value存儲系統(tǒng),是基于內(nèi)存存儲kv的數(shù)據(jù)庫,合理的使用redis作為緩存,可以極大的改善系統(tǒng)的性能和服務器請求響應時間。
redis除了基本的kv存儲以外,還實現(xiàn)了哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets)等數(shù)據(jù)類型;結(jié)合內(nèi)存和數(shù)據(jù)結(jié)構(gòu)的特性,在業(yè)務功能實現(xiàn)的過程中,可以更靈活的實現(xiàn)很多特性。
今天介紹的是有序集合這種數(shù)據(jù)結(jié)構(gòu),我們在實際的業(yè)務過程中使用了有序集合,并且收獲到一些有價值的經(jīng)驗。
什么是有序集合
在redis提供的數(shù)據(jù)類型中,有集合(Set)和有序集合(Sorted Set),在集合中不能添加重復的元素,相同值的元素只能有一個;而有序集合可以給每個元素設(shè)置一個double類型的分數(shù),通過這個值,redis能為集合中的成員進行從小到大的排序。
在redis中,有序集合的實現(xiàn),使用的是一種叫[skiplist]數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)可以讓get、set、add和remove等操作的預期時間達到O(log N),具體的原理,有興趣可以自己了解。
有序集合提供了豐富的操作,可以在很多應用場景應用。
* zunionstore 是求兩個有序集合的并集,可以用來合并兩個投票中所有參與的人的排行榜。
* zinterstore 是求兩個集合的交集,通過它,可以獲得同時參加多個候選人投票的名單列表。
* zrevrank 方便的查詢某個元素在有序集合中的位置,也就是投票的排名。
* zscore 用來查詢某個元素在集合中的分
* zrevrank 返回某個元素在集合中的位置
* zrevrangebyscore 獲取某個分數(shù)區(qū)間內(nèi)元素的排行榜
有序集合提供了從小到大和從大到小兩種排行榜,其中有rev的命令,返回的是從大到小的集合。
設(shè)計投票游戲
之所以會在投票游戲中選用redis,主要考慮高并發(fā)的支持,在實際應用的場景中,因為投票的時候可能有很高的并發(fā)投票和實時投票結(jié)果查詢,如果所有操作都直接操作數(shù)據(jù)庫,那么會對數(shù)據(jù)庫造成較大的負載。經(jīng)過考察技術(shù)方案和實現(xiàn)成本,決定采用redis提供的有序集合,實現(xiàn)投票過程和實時排名的展示,直接讀取緩存,避免了非核心業(yè)務對數(shù)據(jù)庫的突發(fā)高并發(fā)訪問。
投票游戲的用戶故事
1. 創(chuàng)建投票的候選人
2. 創(chuàng)建用戶
3. 用戶參加活動,獲得一定數(shù)量的投票額度
4. 用戶使用投票額度為候選人投票
5. 候選人查看為自己投票的用戶的計票排名
6. 所有人查看實時的候選人選票排名
游戲流程
首先是可以有管理員,創(chuàng)建候選人和用戶,或者候選人和用戶自己注冊,這個取決于具體的場景的需要。本次demo提供的接口是用戶和候選人自己注冊的模式。存儲用戶和候選人信息,最簡單實現(xiàn)可以用redis的字符串類型key/value,本身就是hash,也可以使用redis提供的hash類型。
創(chuàng)建用戶以后,為用戶分配投票額度是要做的工作,通過redis的字符串類型,INCR實現(xiàn),可以保證操作的原子性。投票過程同樣在這個數(shù)據(jù)結(jié)構(gòu)上減去一定的值,但是為了防止并發(fā)情況下,用戶使用超過自己擁有的額度,需要設(shè)計一個鎖,只有在獲得鎖之后,才能做DECR操作。
投票扣減用戶的額度之后,就可以操作核心數(shù)據(jù)結(jié)構(gòu),有序集合。第一步是為特定的候選人增加上獲得的投票,這個是所有候選人的id作為鍵的有序集合,分數(shù)就是獲得的總票數(shù);同時在用戶針對這名候選人的投票記錄上,也記錄每個用戶為同一個候選人投票的排名。
實現(xiàn)上面的操作之后,獲得實時投票排名,就是一件很輕松的工作。有序集合提供的操作可以簡單的查詢出各種排名有關(guān)的名單。
編碼實現(xiàn)redis的調(diào)用
設(shè)計好游戲流程之后,就可以開始直接動手實現(xiàn)了,下面用redis-cli命令,以偽代碼的形式展示一下競猜的整個流程,可以直接在redis客戶端下查看效果。
redis-cli偽代碼
1. 創(chuàng)建用戶和競選的候選人
2. 為用戶分配額度
3. 用戶投票
4. 各種榜單
下圖是運行結(jié)果:
node.js代碼
最后,我們用node.js實現(xiàn)了一個簡單的后端服務demo,javascript的數(shù)據(jù)結(jié)構(gòu)和redis SDK比較清晰的展示原生命令的調(diào)用效果。demo演示了各種api的調(diào)用,可以安裝說明,使用curl調(diào)用對應的接口效果。
實現(xiàn)過程中,我們可以看到,如果直接使用命令,其實整個投票過程只需要非常簡單的幾個命令就可以完成。而demo中演示的代碼,相比命令,增加了很多提供接口訪問和sdk調(diào)用相關(guān)的代碼;如果最后為生產(chǎn)應用編寫一個投票程序,根據(jù)業(yè)務邏輯的需要和容量規(guī)劃,還需要考慮更多的細節(jié),軟件開發(fā)本身也是這樣的過程,從一個簡單的想法和創(chuàng)意開始,然后需要考慮更多的現(xiàn)實場景和需求,不斷的在程序中還原出整個構(gòu)想。
-
Redis
+關(guān)注
關(guān)注
0文章
385瀏覽量
11404
發(fā)布評論請先 登錄
【經(jīng)驗分享】在Omni3576上編譯Redis-8.0.2源碼,并安裝及性能測試

【幸狐Omni3576邊緣計算套件試用體驗】Redis最新8.0.2版本源碼安裝及性能測試
Redis 再次開源!
Redis實戰(zhàn)筆記

華為云 Flexus X 加速 Redis 案例實踐與詳解

華為云Flexus X實例,Redis性能加速評測及對比

華為云 Flexus X 輕松實現(xiàn) Redis 一主多從高效部署

Redis緩存與Memcached的比較
nginx+lua+redis實現(xiàn)灰度發(fā)布
玩轉(zhuǎn)RK3588開發(fā)板基于connector-split 功能實現(xiàn)多屏聯(lián)動

電動汽車有序充電智能管控軟件平臺設(shè)計與應用

評論