成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

玩轉(zhuǎn)Redis - 使用有序集合(sorted sets)實(shí)現(xiàn)投票游戲

AndroidTraveler / 2285人閱讀

摘要:是求兩個(gè)有序集合的并集,可以用來合并兩個(gè)投票中所有參與的人的排行榜。經(jīng)過考察技術(shù)方案和實(shí)現(xiàn)成本,決定采用提供的有序集合,實(shí)現(xiàn)投票過程和實(shí)時(shí)排名的展示,直接讀取緩存,避免了非核心業(yè)務(wù)對(duì)數(shù)據(jù)庫(kù)的突發(fā)高并發(fā)訪問。

redis是一種提供多種數(shù)據(jù)類型的開源key-value存儲(chǔ)系統(tǒng),通常將數(shù)據(jù)全部存儲(chǔ)在內(nèi)存中。

redis是目前最受歡迎的key-value存儲(chǔ)系統(tǒng),是基于內(nèi)存存儲(chǔ)kv的數(shù)據(jù)庫(kù),合理的使用redis作為緩存,可以極大的改善系統(tǒng)的性能和服務(wù)器請(qǐng)求響應(yīng)時(shí)間。

redis除了基本的kv存儲(chǔ)以外,還實(shí)現(xiàn)了哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等數(shù)據(jù)類型;結(jié)合內(nèi)存和數(shù)據(jù)結(jié)構(gòu)的特性,在業(yè)務(wù)功能實(shí)現(xiàn)實(shí)現(xiàn)過程中,可以更靈活的實(shí)現(xiàn)很多特性。

今天介紹的是有序集合,這種數(shù)據(jù)結(jié)構(gòu),我們?cè)趯?shí)際的業(yè)務(wù)過程中使用了有序集合,并且收獲到一些有價(jià)值的經(jīng)驗(yàn)。

什么是有序集合

在redis提供的數(shù)據(jù)類型中,有序集合(Sorted Set)和集合(Set),在集合中不能添加重復(fù)的元素,相同值的元素只能有一個(gè);有序集合不同于集合的是,它可以給每個(gè)元素設(shè)置一個(gè)double類型的分?jǐn)?shù),通過這個(gè)值,redis為集合中的成員進(jìn)行從小到大的排序。

在redis中,有序集合的實(shí)現(xiàn),使用的是一種叫skiplist數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)可以讓get、set、add和remove等操作的預(yù)期時(shí)間達(dá)到O(log N),具體的原理,有興趣可以自己了解。

有序集合提供了豐富的操作,可以在很多應(yīng)用場(chǎng)景應(yīng)用。

zunionstore 是求兩個(gè)有序集合的并集,可以用來合并兩個(gè)投票中所有參與的人的排行榜。

zinterstore 是求兩個(gè)集合的交集,通過它,可以獲得同時(shí)參加多個(gè)候選人投票的名單列表。

zrevrank 方便的查詢某個(gè)元素在有序集合中的位置,也就是投票的排名。

zscore 用來查詢某個(gè)元素在集合中的分?jǐn)?shù)

zrevrank 返回某個(gè)元素在集合中的位置

zrevrangebyscore 獲取某個(gè)分?jǐn)?shù)區(qū)間內(nèi)元素的排行榜

有序集合提供了從小到大和從大到小兩種排行榜,其中有rev的命令,返回的是從大到小的集合。

設(shè)計(jì)投票游戲

之所以會(huì)在投票游戲中選用redis,主要考慮高并發(fā)的支持,在實(shí)際應(yīng)用的場(chǎng)景中,因?yàn)橥镀钡臅r(shí)候可能有很高的并發(fā)投票和實(shí)時(shí)投票結(jié)果查詢,如果所有操作都直接操作數(shù)據(jù)庫(kù),那么會(huì)對(duì)數(shù)據(jù)庫(kù)造成較大的負(fù)載。經(jīng)過考察技術(shù)方案和實(shí)現(xiàn)成本,決定采用redis提供的有序集合,實(shí)現(xiàn)投票過程和實(shí)時(shí)排名的展示,直接讀取緩存,避免了非核心業(yè)務(wù)對(duì)數(shù)據(jù)庫(kù)的突發(fā)高并發(fā)訪問。

投票游戲的用戶故事

創(chuàng)建投票的候選人

創(chuàng)建用戶

用戶參加活動(dòng),獲得一定數(shù)量的投票額度

用戶使用投票額度為候選人投票

候選人查看為自己投票的用戶的計(jì)票排名

所有人查看實(shí)時(shí)的候選人選票排名

游戲流程

首先是可以有管理員,創(chuàng)建候選人和用戶,或者候選人和用戶自己注冊(cè),這個(gè)取決于具體的場(chǎng)景的需要。本次demo提供的接口是用戶和候選人自己注冊(cè)的模式。存儲(chǔ)用戶和候選人信息,最簡(jiǎn)單實(shí)現(xiàn)可以用redis的字符串類型key/value,本身就是hash,也可以使用redis提供的HASH類型。

創(chuàng)建用戶以后,為用戶分配投票額度是要做的工作,通過redis的字符串類型,INCR實(shí)現(xiàn),可以保證操作的原子性。投票過程同樣在這個(gè)數(shù)據(jù)結(jié)構(gòu)上減去一定的值,但是為了防止并發(fā)情況下,用戶使用超過自己擁有的額度,需要設(shè)計(jì)一個(gè)鎖,只有在獲得鎖之后,才能做DECR操作。

投票扣減用戶的額度之后,就可以操作核心數(shù)據(jù)結(jié)構(gòu),有序集合。第一步是為特定的候選人增加上獲得的投票,這個(gè)是所有候選人的id作為鍵的有序集合,分?jǐn)?shù)就是獲得的總票數(shù);同時(shí)在用戶針對(duì)這名候選人的投票記錄上,也記錄每個(gè)用戶為同一個(gè)候選人投票的排名。

實(shí)現(xiàn)上面的操作之后,獲得實(shí)時(shí)投票排名,就是一件很輕松的工作。有序集合提供的操作可以簡(jiǎn)單的查詢出各種排名有關(guān)的名單。

編碼實(shí)現(xiàn)redis的調(diào)用

設(shè)計(jì)好游戲流程之后,就可以開始直接動(dòng)手實(shí)現(xiàn)了,下面用redis-cli命令,以偽代碼的形式展示一下競(jìng)猜的整個(gè)流程,可以直接在redis客戶端下查看效果。

redis-cli偽代碼

創(chuàng)建用戶和競(jìng)選的候選人

set voter:1 0
set voter:2 0
set voter:3 0

set elector:1 name
set elector:2 name

為用戶分配額度

incrby voter:1 50
incrby voter:2 40
incrby voter:3 60

用戶投票

# voter:1
# 增加總榜單
zincrby elector:total:list 25 elector:1
# 增加競(jìng)選人榜單
zincrby elector:single:elector:1 25 voter:1
decrby voter:1 25

# voter:2
zincrby elector:total:list 12 elector:1
zincrby elector:single:elector:1 12 voter:2
decrby voter:2 12

# voter:3
zincrby elector:total:list 40 elector:2
zincrby elector:single:elector:2 40 voter:3
decrby voter:3 40

各種榜單

# 總候選人榜單
zrevrange elector:total:list 0 -1 WITHSCORES

# 投候選人1的名單
zrevrange elector:single:elector:1 0 -1 WITHSCORES

# 創(chuàng)建用戶投票排行
zunionstore voter:total:elector 2 elector:single:elector:1 elector:single:elector:2
# 查看用戶1的排名(返回下標(biāo)從0開始)
zrevrank voter:total:elector voter:1

下圖是運(yùn)行結(jié)果:

node.js代碼
查看代碼Node.js實(shí)現(xiàn)

最后,我們用node.js實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的后端服務(wù)demo,javascript的數(shù)據(jù)結(jié)構(gòu)和redis SDK比較清晰的展示原生命令的調(diào)用效果。demo演示了各種api的調(diào)用,可以安裝說明,使用curl調(diào)用對(duì)應(yīng)的接口效果。

實(shí)現(xiàn)過程中,我們可以看到,如果直接使用命令,其實(shí)整個(gè)投票過程只需要非常簡(jiǎn)單的幾個(gè)命令就可以完成。而demo中演示的代碼,相比命令,增加了很多提供接口訪問和sdk調(diào)用相關(guān)的代碼;如果最后為生產(chǎn)應(yīng)用編寫一個(gè)投票程序,根據(jù)業(yè)務(wù)邏輯的需要和容量規(guī)劃,還需要考慮更多的細(xì)節(jié),軟件開發(fā)本身也是這樣的過程,從一個(gè)簡(jiǎn)單的想法和創(chuàng)意開始,然后需要考慮更多的現(xiàn)實(shí)場(chǎng)景和需求,不斷的在程序中還原出整個(gè)構(gòu)想。

文/liuwill(簡(jiǎn)書作者)
原文鏈接:玩轉(zhuǎn)Redis - 使用有序集合(sorted sets)實(shí)現(xiàn)投票游戲
著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡(jiǎn)書作者”。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97999.html

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)之Redis應(yīng)用~常用命令~應(yīng)用場(chǎng)景(重點(diǎn))(一)

    摘要:數(shù)據(jù)結(jié)構(gòu)之應(yīng)用之常用命令之應(yīng)用場(chǎng)景說明本文參考了開發(fā)實(shí)戰(zhàn)指南,還有實(shí)戰(zhàn)自己之前的筆記。我們正式進(jìn)入主題吧,中種數(shù)據(jù)結(jié)構(gòu)的使用場(chǎng)景介紹。應(yīng)用場(chǎng)景土法建索引。此命令會(huì)覆蓋哈希表中已存在的域。 數(shù)據(jù)結(jié)構(gòu)之Redis應(yīng)用之常用命令之應(yīng)用場(chǎng)景 說明 1、本文參考了Redis開發(fā)實(shí)戰(zhàn)指南GitBook,還有《Redis實(shí)戰(zhàn)》自己之前的筆記。主體框架來自這里。 2、感謝大佬們的付出,在這里自己只是...

    mcterry 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

AndroidTraveler

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<