久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Redis點(diǎn)滴 | Jeff的妙想奇境

 亞典波羅的收藏 2012-07-18

Redis點(diǎn)滴

最近試驗(yàn)在產(chǎn)品中使用Redis來完成以前MongoDB做的一些工作,發(fā)現(xiàn)在大量消息采集的場(chǎng)景下(咱們這次不談查詢什么的),,redis比mongoDB表現(xiàn)更好──這里主要是指編程更簡(jiǎn)便,、邏輯更清晰。下面我舉一些小例子說說Redis都為我們解決了什么問題,,技術(shù)上下文關(guān)鍵字:高并發(fā),、分布式,。

插入與更新操作的無差別性

Redis的所有SET(包括MSET,HMSET)操作都是:存在則更新,,不存在則插入,即insert if not exists,。所以在編程的時(shí)候開發(fā)人員不需要關(guān)心所做的操作屬于更新還是插入,,減免了判斷,因此也避免了判斷操作可能帶來的鎖定,。

MongoDB也有同樣的操作,,update操作的upsert參數(shù)調(diào)為True即可,,不過經(jīng)過測(cè)試,MongoDB為查詢條件為了索引后使用update with upsert來代替insert操作,效率比光insert要低5倍以上,,而redis的HMSET操作的效率要?jiǎng)俪觥?/p>

GETSET的妙用

上一個(gè)經(jīng)驗(yàn)雖說可以解決這條數(shù)據(jù)該“插入還是更新”的問題,,但需要知道當(dāng)前操作是否針對(duì)某數(shù)據(jù)的首次操作的需求還不少。例如我的程序會(huì)在不同時(shí)間接收到同一條消息的不同分片信息包,,我需要在收到該消息的首個(gè)信息包(發(fā)送是無序的)時(shí)做些特殊處理,。

早些時(shí)候的做法是為消息在MongoDB維護(hù)一個(gè)狀態(tài)對(duì)象,有信息包來的時(shí)候就走“上鎖->檢查消息狀態(tài)->根據(jù)狀態(tài)決定做不做特殊操作->解鎖” 這個(gè)流程,,雖然同事已經(jīng)把鎖的粒度控制得非常細(xì)了,,但有鎖的程序遇上多實(shí)例部署就歇了。

Redis的GETSET是解決這個(gè)問題的終極武器,,只需要把當(dāng)前信息包的唯一標(biāo)識(shí)對(duì)指定的狀態(tài)屬性進(jìn)行一次GETSET操作,,再判斷返回值是否為空則知道是否首次操作。GETSET替我們把兩次讀寫的操作封裝成了原子操作,,V5啊,。

山寨版數(shù)據(jù)過期策略

我曾經(jīng)想過要寫服務(wù)器端的腳本來擴(kuò)展redis,試圖要拿到數(shù)據(jù)過期的事件,,用來做一些回調(diào)來處理過期數(shù)據(jù),,但很快我發(fā)現(xiàn)這個(gè)不現(xiàn)實(shí)。于是我選擇通過使用排序集合(SORTEDSET)來實(shí)現(xiàn)一個(gè)山寨的數(shù)據(jù)過期策略:需要定時(shí)過期的數(shù)據(jù),,統(tǒng)一添加到一個(gè)排序集合:ZADD expiringKey timestamp data,。在這里我使用了時(shí)間值(毫秒為單位的長(zhǎng)整型)作為數(shù)據(jù)的分?jǐn)?shù),那么很自然的,,早期的數(shù)據(jù)總會(huì)排在集合前面,;然后我寫一個(gè)程序會(huì)定時(shí)地過來打理這些過期的數(shù)據(jù)就好了。

存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)

例如有“通訊錄”這樣的數(shù)據(jù),,包含有”name”,”city”,”gender”等8個(gè)屬性,,使用mongoDB保存就很簡(jiǎn)單,創(chuàng)建一個(gè) Document,,設(shè)置屬性后存儲(chǔ)即可,,而Redis本身并非Document型的DB而是Key Value DB,要存儲(chǔ)這種數(shù)據(jù),,還得在Key上面花一點(diǎn)功夫:使用 contact:id:name,contact:id:city,contact:id:gender之類的Key來存儲(chǔ)其對(duì)應(yīng)的值,。當(dāng)然,這只是使用 redis存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)最原始的辦法,,更建議的辦法是使用Hash存儲(chǔ),,如 hmset contact:id name jeff contact [email protected] gender male。相對(duì)set操作而言,hmset既節(jié)省了存儲(chǔ)空間又提高了存儲(chǔ)效率,。

使用MongoDB來存儲(chǔ)這些數(shù)據(jù)是小菜一碟,,但鑒于第一點(diǎn)經(jīng)驗(yàn),我還是愿意使用Redis,。

比較可惜的是,,目前Redis的Hash存儲(chǔ)僅支持字符類型的值,不支持其他數(shù)據(jù)結(jié)構(gòu),,我非常期待它日后會(huì)支持其他數(shù)據(jù)結(jié)構(gòu),,甚至支持Hash的嵌套。關(guān)于這點(diǎn),,@wuvist 同學(xué)認(rèn)為十分有可能,。

小結(jié)

上面這些Case都只是Redis牛刀小用,但實(shí)際上給程序帶來的便利是非常明顯的,,最明顯的就是可以把原來的程序上使用的鎖都拋棄掉,,甚至直接支持分布式運(yùn)行和水平擴(kuò)展了。

順便在此小結(jié)一點(diǎn)高并發(fā)分布式應(yīng)用程序編寫的一些推薦的注意事項(xiàng)吧,,當(dāng)然這是我的個(gè)人偏好并結(jié)合了一些特定業(yè)務(wù)領(lǐng)域的性質(zhì):

1. 程序?qū)Y源最好是只讀或只寫,,明確分工。不要在一個(gè)程序里同時(shí)對(duì)資源進(jìn)行讀寫,,除非是原子操作,,如GETSET。
2. 寫操作中,,插入與更新最好是無差別的,,避免程序?qū)Υ诉M(jìn)行行判斷,破壞操作的原子性,。
3. 更新過程中盡最不要對(duì)更新值和原值進(jìn)行比較,,還是關(guān)乎操作的原子性,如果真要進(jìn)行比較,,有兩種方案供參考,。
1). 更新時(shí),為字段追加新數(shù)據(jù),,使用集合(如果是數(shù)值使用排序集合更好)來存儲(chǔ),;比較的邏輯交給讀取的程序處理。
2). 使用CAS,,類似樂觀鎖,,實(shí)現(xiàn)多進(jìn)程數(shù)據(jù)安全控制。如果目標(biāo)資源的服務(wù)器支持最佳,。
4. 還是那一句,,避免在程序里面使用鎖。逼不得已就用分布式鎖吧,。
5. 多線程是萬惡之源,,要慎用,一條線程能把CPU跑滿才是真牛,,多核,、擴(kuò)容時(shí)可考慮多進(jìn)程。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多