国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

開發(fā)如何避免redis集群訪問傾斜和數(shù)據(jù)傾斜

wangzy2019 / 1389人閱讀

摘要:另外還有一件事值得一提,默認情況下,我們在生成的時候,會把隨機數(shù)作為的后綴,這樣符合的命名空間,方便的收歸和管理。所以,對于很長名的,要對隨機數(shù)的放入做謹慎處理,比如放在在最后一個命令空間的最前面由原來的改成。

[TOC]

概述

redis 集群部署方式大部分采用類 Twemproxy 的方式進行部署。即通過 Twemproxy 對 redis key 進行分片計算,將 redis key 進行分片計算,分配到多個 redis 實例中的其中一個。tewmproxy 架構圖如下:

由于 Twemproxy 背后的多個 redis 實例在內存配置和 cpu 配置上都是一致的,所以一旦出現(xiàn)訪問量傾斜或者數(shù)據(jù)量傾斜,則可能會導致某個 redis 實例達到性能瓶頸,從而使整個集群達到性能瓶頸。

hot key出現(xiàn)造成集群訪問量傾斜

Hot key,即熱點 key,指的是在一段時間內,該 key 的訪問量遠遠高于其他的 redis key, 導致大部分的訪問流量在經(jīng)過 proxy 分片之后,都集中訪問到某一個 redis 實例上。hot key 通常在不同業(yè)務中,存儲著不同的熱點信息。比如

新聞應用中的熱點新聞內容;

活動系統(tǒng)中某個用戶瘋狂參與的活動的活動配置;

商城秒殺系統(tǒng)中,最吸引用戶眼球,性價比最高的商品信息;

……

解決方案 1. 使用本地緩存

在 client 端使用本地緩存,從而降低了redis集群對hot key的訪問量,但是同時帶來兩個問題:1、如果對可能成為 hot key 的 key 都進行本地緩存,那么本地緩存是否會過大,從而影響應用程序本身所需的緩存開銷。2、如何保證本地緩存和redis集群數(shù)據(jù)的有效期的一致性。
針對這兩個問題,先不展開講,先將第二個解決方案。

2. 利用分片算法的特性,對key進行打散處理

我們知道 hot key 之所以是 hot key,是因為它只有一個key,落地到一個實例上。所以我們可以給hot key加上前綴或者后綴,把一個hotkey 的數(shù)量變成 redis 實例個數(shù)N的倍數(shù)M,從而由訪問一個 redis key 變成訪問 N * M 個redis key。
N*M 個 redis key 經(jīng)過分片分布到不同的實例上,將訪問量均攤到所有實例。

代碼如下:

//redis 實例數(shù)
const M = 16

//redis 實例數(shù)倍數(shù)(按需設計,2^n倍,n一般為1到4的整數(shù))
const N = 2

func main() {
//獲取 redis 實例 
    c, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }
    defer c.Close()

    hotKey := "hotKey:abc"
    //隨機數(shù)
    randNum := GenerateRangeNum(1, N*M)
    //得到對 hot key 進行打散的 key
    tmpHotKey := hotKey + "_" + strconv.Itoa(randNum)
    
    //hot key 過期時間
    expireTime := 50
    
    //過期時間平緩化的一個時間隨機值
    randExpireTime := GenerateRangeNum(0, 5)

    data, err := redis.String(c.Do("GET", tmpHotKey))
    if err != nil {
        data, err = redis.String(c.Do("GET", hotKey))
        if err != nil {
            data = GetDataFromDb()
            c.Do("SET", "hotKey", data, expireTime)
            c.Do("SET", tmpHotKey, data, expireTime + randExpireTime)
        } else {
            c.Do("SET", tmpHotKey, data, expireTime + randExpireTime)
        }
    }
}

在這個代碼中,通過一個大于等于 1 小于 M * N 的隨機數(shù),得到一個 tmp key,程序會優(yōu)先訪問tmp key,在得不到數(shù)據(jù)的情況下,再訪問原來的 hot key,并將 hot key的內容寫回 tmp key。值得注意的是,tmp key的過期時間是 hot key 的過期時間加上一個較小的隨機正整數(shù),保證在 hot key 過期時,所有 tmp key 不會同時過期而造成緩存雪崩。這是一種通過坡度過期的方式來避免雪崩的思路,同時也可以利用原子鎖來寫入數(shù)據(jù)就更加的完美,減小db的壓力。

另外還有一件事值得一提,默認情況下,我們在生成 tmp key的時候,會把隨機數(shù)作為 hot key 的后綴,這樣符合redis的命名空間,方便 key 的收歸和管理。但是存在一種極端的情況,就是hot key的長度很長,這個時候隨機數(shù)不能作為后綴添加,原因是 Twemproxy 的分片算法在計算過程中,越靠前的字符權重越大,考后的字符權重則越小。也就是說對于key名,前面的字符差異越大,算出來的分片值差異也越大,更有可能分配到不同的實例(具體算法這里不展開講)。所以,對于很長 key 名的 hot key,要對隨機數(shù)的放入做謹慎處理,比如放在在最后一個命令空間的最前面(eg:由原來的 space1:space2:space3_rand 改成 space1:space2:rand_space3)。

big key 造成集群數(shù)據(jù)量傾斜

big key ,即數(shù)據(jù)量大的 key ,由于其數(shù)據(jù)大小遠大于其他key,導致經(jīng)過分片之后,某個具體存儲這個 big key 的實例內存使用量遠大于其他實例,造成,內存不足,拖累整個集群的使用。big key 在不同業(yè)務上,通常體現(xiàn)為不同的數(shù)據(jù),比如:

論壇中的大型持久蓋樓活動;

聊天室系統(tǒng)中熱門聊天室的消息列表;

……

解決方案 對 big key 進行拆分

對 big key 存儲的數(shù)據(jù) (big value)進行拆分,變成value1,value2… valueN,

如果big value 是個大json 通過 mset 的方式,將這個 key 的內容打散到各個實例中,減小big key 對數(shù)據(jù)量傾斜造成的影響。

//存
mset key1, vlaue1, key2, vlaue2 ... keyN, valueN
//取
mget key1, key2 ... keyN

如果big value 是個大list,可以拆成將list拆成。= list_1, list_2, list3, listN

其他數(shù)據(jù)類型同理。

既是big key 也是 hot key

在開發(fā)過程中,有些 key 不只是訪問量大,數(shù)據(jù)量也很大,這個時候就要考慮這個 key 使用的場景,存儲在redis集群中是否是合理的,是否使用其他組件來存儲更合適;如果堅持要用 redis 來存儲,可能考慮遷移出集群,采用一主一備(或1主多備)的架構來存儲。

其他 如何發(fā)現(xiàn) hot key,big key 1. 事前-預判

在業(yè)務開發(fā)階段,就要對可能變成 hot key ,big key 的數(shù)據(jù)進行判斷,提前處理,這需要的是對產品業(yè)務的理解,對運營節(jié)奏的把握,對數(shù)據(jù)設計的經(jīng)驗。

2.事中-監(jiān)控和自動處理
監(jiān)控

在應用程序端,對每次請求 redis 的操作進行收集上報;不推薦,但是在運維資源缺少的場景下可以考慮。開發(fā)可以繞過運維搞定);

在proxy層,對每一個 redis 請求進行收集上報;(推薦,改動涉及少且好維護);

對 redis 實例使用monitor命令統(tǒng)計熱點key(不推薦,高并發(fā)條件下會有造成redis 內存爆掉的隱患);

機器層面,Redis客戶端使用TCP協(xié)議與服務端進行交互,通信協(xié)議采用的是RESP。如果站在機器的角度,可以通過對機器上所有Redis端口的TCP數(shù)據(jù)包進行抓取完成熱點key的統(tǒng)計(不推薦,公司每臺機器上的基本組件已經(jīng)很多了,別再添亂了);

自動處理

通過監(jiān)控之后,程序可以獲取 big key 和 hot key,再報警的同時,程序對 big key 和 hot key 進行自動處理。或者通知程序猿利用一定的工具進行定制化處理(在程序中對特定的key 執(zhí)行前面提到的解決方案)

3.事后

盡量還是不要事后了吧,都是血和淚的教訓,不展開講。

謝謝閱讀,歡迎交流。

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

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29800.html

相關文章

  • 什么是一致性Hash算法?

    摘要:五一致性算法的容錯性和可擴展性現(xiàn)假設不幸宕機,可以看到此時對象不會受到影響,只有對象被重定位到。綜上所述,一致性算法對于節(jié)點的增減都只需重定位環(huán)空間中的一小部分數(shù)據(jù),具有較好的容錯性和可擴展性。 最近有小伙伴跑過來問什么是Hash一致性算法,說面試的時候被問到了,因為不了解,所以就沒有回答上,問我有沒有相應的學習資料推薦,當時上班,沒時間回復,晚上回去了就忘了這件事,今天突然看到這個,...

    feng409 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<