顯示具有 redis 標籤的文章。 顯示所有文章
顯示具有 redis 標籤的文章。 顯示所有文章

2018年1月12日 星期五

使用Redis之後碰到的一些地雷雷雷...(Orz

最近開始嘗試使用Redis Sentinel建置高可用性服務,在測試的時候碰到一些問題。我在一個由三個Redis實體組成的Master-Slave Cluster倒入約4GB的資料,然後在Master下KEYS *把所有鍵列出來,沒過幾秒在Sentinel出現Master down然後重新推舉Master的訊息。

我在Sentinel裡頭設定Master在5秒內無回應就會判定為down,那也就是說我做了列出所有鍵的操作阻擋了後續所有連線的作業,這是怎麼回事?

回想一下Redis的特性,大概是:
  • 單執行緒、單行程
  • 所有操作是以atomic方式進行,因此確保了資料的一致性
  • 雖然運作時資料是存放於記憶體中,但是可回存為檔案,確保資料的持久性
  • 因為資料是存放於記憶體,所以速度很快
Redis不像一般的RDBMS有實做Transaction Isolation,任何操作都要等到前一個操作執行完才會進行,無法平行處理,Redis才能保證資料的一致性。因此非常不適合使用Redis進行以下操作:
  • 列出所有鍵:KEYS *
    如果存入的鍵很多,就得花很多時間處理。以我測試的情況,4GB的資料有將近1500萬個鍵,列出操作就花了183秒。
  • 搜尋特定鍵:KEYS *name*
    跟前一個是同樣的情況,列出了154個卻花了9秒多來處理。
我本職是系統管理者不是程式開發人員,所以有可能有其他的情況不適合使用Redis。如果要更有效率的使用Redis,那就盡量不要使用KEYS指令來列出或搜尋鍵。

2017年12月13日 星期三

GCE的TCP Health Check不支援換行符號

我打算在Google Compute Engine上建置Redis Slave個體群組,並使用GCP的負載平衡服務來連接,但是碰到一個問題,Health Check永遠都是失敗,導致個體群組裡頭的VM一直被重建。

檢查了許多地方,確認Health Check的IP可以連進VM,從netstat -an也可以看到連線。使用nc -l -p 6379的確也能看到Health Check送進來的要求字串 PING\r\n,但是透過redis-cli下monitor指令卻沒看到。

我在Health Check設置的要求字串是 PING\r\n,檢查字串是 +PONG,用nc的確是看到傳進來的是PING\r\n....等等,換行字元應該不會顯示?然後又用PYTHON參考別人寫的範例做了一個TCP SOCKET SERVER,結果顯示出來的是 PING\\r\\n...... Orz。redis一定要接收到換行符號才算接收到指令,否則就會停在那裡。看起來GCE的Health Check會過濾特殊符號。

Google Groups上的GCE論壇也有人有相同的問題,Google的人回答都指向stackoverflow上的某個連結:
https://stackoverflow.com/questions/43228878/health-check-to-detect-redis-master-from-google-tcp-load-balancer
下面回答得很長,其實結論是在同一台VM裡頭去跑另一隻程式來處理Health Check請求與回傳結果,我最後是用PYTHON寫了一個TCP SOCKET SERVER,當Health Check傳入PING,就使用subprocess去跑redis-cli PING,然後把結果回傳。


2014年12月18日 星期四

CentOS 7, systemd, redis, max open files

在CentOS 7安裝好Redis,預設redis會開啟10000的檔案,所以啟動之後log總會顯示以下錯誤:
Current maximum open files is 1024. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
即使修改/etc/security/limits.conf也沒有用,這個檔案一開頭就說:
This file sets the resource limits for the users logged in via PAM.
It does not affect resource limits of the system services.
因為CentOS 7用systemd換掉ntsysv,網路上有提示解法,就是修改redis的systemd配置檔案/lib/systemd/system/redis.service正確來說是/etc/systemd/system/redis.service.d/limit.conf,把LimitNOFILE=10240後面的數字改成所需的。

修改之後,要先重新載入systemd,否則會出現警告。如下
$ service redis restart
Redirecting to /bin/systemctl restart  redis.service
Warning: Unit file of redis.service changed on disk, 'systemctl daemon-reload' recommended.