一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Redis點滴 | Jeff的妙想奇境

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

Redis點滴

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

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

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

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

GETSET的妙用

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

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

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

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

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

存儲結構化數(shù)據(jù)

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

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

比較可惜的是,目前Redis的Hash存儲僅支持字符類型的值,不支持其他數(shù)據(jù)結構,我非常期待它日后會支持其他數(shù)據(jù)結構,甚至支持Hash的嵌套。關于這點,@wuvist 同學認為十分有可能。

小結

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

順便在此小結一點高并發(fā)分布式應用程序編寫的一些推薦的注意事項吧,當然這是我的個人偏好并結合了一些特定業(yè)務領域的性質(zhì):

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲中文字幕三区四区| 久久精品中文字幕人妻中文| 在线视频三区日本精品| 极品少妇一区二区三区精品视频| 2019年国产最新视频| 日韩三级黄色大片免费观看| 色综合久久超碰色婷婷| 一区二区三区亚洲国产| 好吊妞视频只有这里有精品| 国产成人午夜av一区二区 | 国产亚洲欧美日韩精品一区| 日韩精品视频香蕉视频| 国产老女人性生活视频| 国产日韩欧美专区一区| 亚洲一区二区精品久久av| 日本在线高清精品人妻| 又色又爽又黄的三级视频| 国产精品第一香蕉视频| 激情综合五月开心久久| 日本加勒比在线观看一区| 欧洲偷拍视频中文字幕| 女同伦理国产精品久久久| 亚洲av日韩av高潮无打码| 亚洲国产av一二三区| 亚洲欧美天堂精品在线| 国产又爽又猛又粗又色对黄| 国产美女精品人人做人人爽| 亚洲一区二区三区三州| 91人妻人人揉人人澡人| 日韩欧美综合在线播放| 欧美胖熟妇一区二区三区| 在线免费国产一区二区三区 | 夫妻激情视频一区二区三区| 国产欧美一区二区三区精品视| 东京热男人的天堂久久综合| 加勒比系列一区二区在线观看| 亚洲精品国产精品日韩| 特黄大片性高水多欧美一级| 亚洲综合精品天堂夜夜| 91午夜少妇极品福利| 91欧美日韩国产在线观看|