Sharing

2012年8月31日 星期五

Rabbitmq 使用心得


http://www.rabbitmq.com/

最近使用 rabbitmq 來架構一個 High available 的 message framework, 不過使用了一陣子之後發現其實它在 HA 的部份仍然有不少的問題, 分享出來給大家參考.

Rabbitmq 是一個 broker 的角色, 整個傳遞訊息的詳細流程是

clientA -> broker -> queue -> clientB

所以如果要確保 clientA 送出去的訊息 clientB 一定會收到, 那 broker/queue 都必須要有 redundant 的機制, 否則任一個環節出問題時, 都會造成訊息無法傳送到對方手裡, 先看 broker 的部份

http://www.rabbitmq.com/clustering.html

文件中寫的還滿清楚的, 有幾個要注意的點
1. /var/lib/rabbitmq/.erlang.cookie 要同步
2. 加入 cluster 的方式有兩種, 一種是 disk, 另一種是 ram

除此之外, 魔鬼就藏在細節中

第一個問題是 RabbitMQ clustering does not tolerate network partitions well

前陣子的文檔並沒有說明這點, 我也是在實驗之後才發現這件事, 用下面這張圖來解釋, 原本的 B1 ~ B5 組成 cluster, 但可能因為 B1 和 B2 所在的 Switch 壞掉了, 所以把 B1 ~ B5 切成了上下兩個 cluster. 在這種狀況下, 雙方都可以正常運作, 但當我們把壞掉的 Switch 換掉之後, 卻發現上下兩個 cluster 卻不會自動回復成一個 cluster. 你再也無法從 cluster A 內的點送訊息到 cluster B 內的點.


這篇是討論一樣的問題
http://rabbitmq.1065348.n5.nabble.com/Cluster-recovery-due-to-network-outages-td14359.html


在文檔中雖然有提到 cluster 不適合 WAN, 所以建議使用 shovel/federation 但就實際面來看, 即使是 LAN 也還是會遇到 network partition 的事件, 當遇到這種狀況時, 你必須要重啟其中任何一個 broker, 讓它重新去掃所有的 cluster 成員, 這時候上下兩個 cluster 就會再合併起來了.


第二個問題是 broker cluster 對於 fail recover 的程序不是很方便

There are some important caveats:
  • All disk nodes must be running for certain operations, most notably leaving a cluster, to succeed.
  • At least one disk node should be running at all times.
  • When all nodes in a cluster have been shut down, restarting any node will suspend for up to 30 seconds and then fail if the last disk node that was shut down has not been restarted yet. Since the nodes do not know what happened to that last node, they have to assume that it holds a more up-to-date version of the broker state. Hence, in order to preserve data integrity, they cannot resume operation until that node is restarted.

上面的說明的情況就是當你的 cluster 建立起來之後, 如果你要全面關機維修時, 你一定要記得最後關的是那一台, 而那一台在關機維修之後, 必須要先開機, 你無法以任意的順序開機. 其實這種狀況一般來說是不太容易遇到的, 因為"全面"關機不是一個機房該做的事, 應該是依序維修, 一台維修完就立即開機, 再繼續維修下一台. 但考慮到一個機房遇到最糟的事情就是發生了斷電, 即使全部的機器依序自動關機, 那請問下次開機時, 你要如何知道那一台是最後關機的?!

另外我也針對某個特殊狀況進行模擬, 如果最後有三台機器在同一秒內關機, 那下次開機時, 誰要先開啟? 答案是誰先開啟都沒用, 這三台必須要同步開機後, 同步把 rabbitmq-server 重啟, 才能夠把 cluster 重建回來. 相當的麻煩, 我在下面這個連結內也看到同樣的討論, 目前是還沒有解答的.

http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2012-June/020594.html

第三個問題是 Upgrade cluster 必須要將全部的服務停止

All nodes in a cluster must be running the same versions of Erlang and RabbitMQ, although they may have different plugins installed. Therefore it is necessary to stop all nodes in the cluster, then start all nodes when performing an upgrade. While not strictly necessary, it is a good idea to decide ahead of time which disc node will be the upgrader, stop that node last, and start it first

升級竟然需要把 cluster 全部停止, 而且最後停止服務的點在升級後, 必須要先啟動, 我想升級需要把 cluster 全部停止這件事, 應該是一件滿嚴重的事情


討論完了 broker 的部份, 再來看一下 queue 的部份, 為什麼 queue 也需要 HA 呢?

http://www.rabbitmq.com/clustering.html 內有這樣一句話
An exception to this are message queues, which by default reside on the node that created them.

這表示 queue 只存在在某一個特定的 broker node 上, 如果當這個 broker 壞掉時, 你這個 queue 也就跟著消失, 無法透過其它的 broker 來存取, 下面這個網頁第一段話也寫的很清楚

http://www.rabbitmq.com/ha.html
If your RabbitMQ broker consists of a single node, then a failure of that node will cause downtime, temporary unavailability of service, and potentially loss of messages (especially non-persistent messages held by non-durable queues)

所以 rabbitmq 提供了 mirrored queue 這個機制, 然而機制只把這個故事講完了一半, 網頁中還寫到

Clients that were consuming from the mirrored-queue and support our Consumer Cancellation Notifications extension will receive a notification that their subscription to the mirrored-queue has been abruptly cancelled. At this point they should re-consume from the queue, which will pick up the new master

也就是 client 端還必須要自行 handle 一個 cancel event, 然後要自動的連結到新的 queue, 才有辦法拿到 message, 就我目前 survey 的狀況來看, 目前還沒有 client 端的程式 (kombu/pika/pyamqp), 有處理好這個問題. 如果這個狀況有變化的話, 還麻煩也通知我一聲.

有關 rabbitmq HA 的問題, 在官網上他們也寫了一篇目前 rabbitmq 還缺少的部份, 我覺得還滿有誠意的, 至少把問題都列出來, 除了表示他們已注意到這些問題, 未來可能會修掉之外, 使用者也可以先自行了解如果使用 rabbitmq 會有什麼副作用, 可以先打預防針
http://www.rabbitmq.com/blog/2011/10/25/high-availability-in-rabbitmq-solving-part-of-the-puzzle/


因為 Openstack 也很仰賴 rabbitmq, 所以類似的討論串我也 openstack 的論壇上也有看到
http://wiki.openstack.org/RabbitmqHA
http://www.mail-archive.com/openstack@lists.launchpad.net/msg07495.html
http://www.mail-archive.com/openstack@lists.launchpad.net/msg07502.html
http://www.mail-archive.com/openstack@lists.launchpad.net/msg07595.html

有些是 Celery 的討論區看到的
http://comments.gmane.org/gmane.comp.python.amqp.celery.user/1291
https://groups.google.com/forum/#!searchin/celery-users/cluster/celery-users/8EqwvV4IZ2g/MGmSv-P8Q8kJ

其它相關討論
http://www.vnext.org/mirrored-queues-and-preserving-messages


如果有朋友對 distributed message queue 也有興趣的話, 也歡迎一起討論, 台灣對這塊的東西討論實在不太多.

2012年8月7日 星期二

Get the Google Plus RSS Feeds

很習慣用 google reader 來追蹤我要讀的部落格,
最近開始有一些人放棄用 blogger, 改用 google plus 公開發表文章
所以就上網找了方法如何把 google plus 的文章變成 RSS Feeds
方法看起來不少, 但以下這個是我試用過而且最簡單的方式

http://pipes.yahoo.com/pipes/pipe.info?_id=492912b192fbc50c159d84700b79d6a2

MegaRAID Storage Manager on Ubuntu 12.04


LSI 出的 Storage Manager 分成 Client 端和 Server 端, 也就是你可以在 Storage Server 裝 daemon, 然後在 Windows 上面來觀看整體的狀況

你可以在下面這個連結看到 LSI 所有的 Tool, 你可以在裡面找到 Windows 及 Linux 版本的 MegaRAID Storage Manager, 兩個都需要下載
http://www.lsi.com/search/Pages/downloads.aspx?k=*

或是進到 RaidCard 的網頁, 選擇 Support & Downloads 也可以找到
http://www.lsi.com/products/storagecomponents/Pages/MegaRAIDSAS9260-4i.aspx

這邊是目前最新的 5.3 版本
http://www.lsi.com/downloads/Public/MegaRAID%20Common%20Files/12.05.03.00_Linux_MSM.zip
http://www.lsi.com/downloads/Public/MegaRAID%20Common%20Files/12.05.03.00_Windows_MSM.zip

首先在 linux 上安裝 storage manager, 不過應該 LSI 提供的是 .rpm 安裝檔, 所以我們就利用 alien 來編出 .deb 檔案

pjack@ubuntu-001:~/msm$ unzip 12.05.03.00_Linux_MSM.zip
Archive:  12.05.03.00_Linux_MSM.zip
  inflating: MSM_linux_x64_installer-12.05.03-00.tar.gz
  inflating: MSM_linux_installer-12.05.03-00.tar.gz
  inflating: 12.05.03.00_Linux_MSM.txt
pjack@ubuntu-001:~/msm$ tar xzf MSM_linux_x64_installer-12.05.03-00.tar.gz
pjack@ubuntu-001:~/msm/disk$ cd disk
pjack@ubuntu-001:~/msm/disk$ sudo apt-get install alien
pjack@ubuntu-001:~/msm/disk$ sudo alien --scripts *.rpm
lib-utils_1.00-10_all.deb generated
lib-utils2_1.00-5_all.deb generated
megaraid-storage-manager_12.05.03-1_all.deb generated
sas-ir-snmp_12.05-202_amd64.deb generated
sas-snmp_12.05-201_amd64.deb generated

編好之後, 會產生五個 .deb 檔, 但我們不需要全裝, 事實上後面兩個 sas*.deb 會裝不起來, 會顯示
SAS-IR SNMP Agent supports only Redhat and SuSE releases.
但沒關係, 我們只需要前三個, 裝好之後, 會看到 "in getClientList" 一直出現, 他是用 java 寫的 program, 所以我們先把所有的 java process 砍掉

pjack@ubuntu-001:~/msm/disk$ sudo dpkg -i lib-utils2_1.00-5_all.deb
pjack@ubuntu-001:~/msm/disk$ sudo dpkg -i lib-utils_1.00-10_all.deb
pjack@ubuntu-001:~/msm/disk$ sudo dpkg -i megaraid-storage-manager_12.05.03-1_all.deb
pjack@ubuntu-001:~/msm/disk$ sudo killall java

接下來記得把 /etc/init.d/vivaldiframeworkd 裡面開頭改成 #!/bin/bash, 然後重啟 daemon
Linux 這樣子就裝好了, 如果要驗証, 就看一下有沒有 java virtual machine 在跑
pjack@ubuntu-001:~/msm/disk$ sudo nano /etc/init.d/vivaldiframeworkd
pjack@ubuntu-001:~/msm/disk$ sudo service vivaldiframeworkd restart
pjack@ubuntu-001:~/msm/disk$ ps aux | grep java
root     22618 56.3  0.0 34289664 69288 pts/0  Sl   14:35   0:01 ../jre/bin/java -classpath ../jre/lib/rt.jar:../jre/lib/jsse.jar:../jre/lib/jce.jar:mail.jar:Framework.jar -Djava.library.path=. Framework.FrameworkManager


如果不小心裝了 sas 開頭的那兩個 package, 要反安裝可能會失敗, 就造成 dpkg 亂掉, 請用以下方法解除

pjack@ubuntu-001:~$ sudo rm /var/lib/dpkg/info/sas*.prerm
pjack@ubuntu-001:~$ sudo dpkg -P sas-snmp
pjack@ubuntu-001:~$ sudo dpkg -P sas-ir-snmp

Window 上的安裝應該不用解釋, zip 檔下載下來後解來開, 然後執行 setup.exe
安裝好之後, 開始 -> 所有程式 -> MegaRaid Storage Manager -> StartUp UI
輸入剛剛那台 linux 的 ip, 順利的話應該就可以 discovery 到這台

進去後, 就會列出所有這台有連結到 RaidCard 的硬碟