Redis 使用雜談

Ensky Lin
3 min readDec 7, 2019

--

redis 是個非常好用的工具,網路上有太多文章在介紹如何安裝、使用、以及有什麼功能,在此不贅述。我就 focus 在敝公司我的使用情境上遇到一些我們之前沒意識到的問題。

我們拿來幹麻

某個古老的產品一直以來 daemon 和 deamon 之間溝通的方式就是透過 domain socket 直接對對方下指令,因為功能日漸龐大的關係,有很多細節問題並不想在一開始處理 (ex. delay 送 job、retry 機制、對面的 daemon 因為某些原因掛掉,sender 就會卡住等等)

我們決定改成使用 Message Queue 類似的機制,先是 survey 了幾套現成的 Job Queue,kafka、RabbitMQ、甚至不太像 job queue 的 zeroMQ 等,但不是啟動太 heavy 就是記憶體用量過大,反正不符我們需求。

因此就把歪腦筋動到 Redis 身上,非常 lightweight、也已經非常穩定,完全可以依賴它建構一個非常可靠的服務。

因此我們透過 Redis 在上面用 C++ 打造了一套 JobQueue system,包含一些功能像是 retry、delay job、priority 等等,反正足夠我們使用,一開始使用上也相當不錯(乍看之下)。我們透過 redis 的 AOF 和 RDB 功能達到 persistent Message Queue 功能。

問題來了

AOF Startup slow problem

AOF 好用歸好用,但是有個有點大的硬傷是啟動的時候會花你不確定多少時間來 initialize redis,這造成我們的啟動時間不確定,而 redis 啟動的時間你都沒辦法塞 job 進去,有點困擾。

啟動的時間和 AOF 大小有關,這可以透過 config 中的
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

值來設定,照這個設定就是 AOF 大小到了 64mb 之後 100% 會重寫,但我們實測結果還是有超過 64mb 的狀況,並沒有像他說的那麼美好。

啟動時間不確定性這點造成我們小小困擾,那時還寫了 polling redis startup 來達到確保 redis 可用。

RDB Disk bandwidth 100% problem

那如果不用 AOF 只用 RDB 呢?

RDB 寫檔的機制是 redis 本身會先 fork 然後把 memory 全部一次寫進去 rdb 檔案再換掉原本的 rdb 檔案,但這會導致 rdb dump 那瞬間 disk IO 會直接被吃滿,也造成 application 效能會因此被影響。

一般 cloud 上解決方式通常是用 replication 先丟到另外一台,就想幹麻就可以幹麻了。(但我們不能)

Queue Full problem

這其實滿可以想像的,Redis 畢竟是存在記憶體,一旦你的 worker 因為某些事情而 delay 處理 job 或是它掛了再起不能,你的 redis 就會直接塞爆,通常可以透過一些機制處理掉(限制 queue 大小、drop job、服務偵測等)。

總結

新服務總是會帶來新問題,就算你覺得某個東西很穩定想起來一定用起來沒啥問題,但實務上使用的時候還是會需要手動解掉一些意想不到的事情。

--

--