Rama是Red Planet Labs創造的分散式程式平台,用Java跟Clojure寫成。這裡紀錄我把1.9.0的release解開、啟動rama cluster的過程。release zip檔案解壓出來的內容
. ├── lib ├── LICENSE.txt ├── log4j2.properties ├── logs ├── rama ├── rama.jar ├── rama.yaml └── README.md
常駐行程 [local-0]
Rama叢集由三個常駐行程組成:
- Zookeeper:存叢集metadata。Rama透過一層叫Metastore的抽象使用它,記錄哪個節點該跑哪些module worker、以及replication的leader election
- Conductor:CLI的接口,同時提供web版的Cluster UI,負責管理模組部署
- Supervisor:每台工作機跑一個,負責處理實際執行運算的worker process的調度
各自要獨立執行:
# 內建的單機 ZK,官方標注不適合正式環境 nohup ./rama devZookeeper >/dev/null 2>&1 & nohup ./rama conductor >/dev/null 2>&1 & nohup ./rama supervisor >/dev/null 2>&1 &
listening ports
2000 zookeeper 1973 conductor <- CLI client 只需要這個 8888 cluster UI 3000 supervisor HTTP ┐ 3001 worker ├ supervisor.port.range 的前幾個 port 3002 worker ┘
Conductor的UI開在8888,裡面有相當豐富的runtime telemetry。要讓那些數字有東西可看,要先部署內建的monitoring模組,也順手設定一下遙測的保留期避免把磁碟吃光:
./rama deploy --action launch --systemModule monitoring --tasks 4 --threads 2 --workers 1 ./rama monitoringConfig --setRetention 60,90000
Problem port range的寬度限制 [local-1]
Supervisor會拿 supervisor.port.range 的第一個 port 開自己的HTTP server,worker則往後依序取用。如果預設的 [3000, 4000] 跟機器上其他東西撞到,就需要更改這個設定
我改成 [3100, 4000],結果每一個CLI指令都開始噴 Invalid config,連唯讀的 confValue 都不能用了,表示config驗證發生在所有指令的共同路徑上
文件說明只有說「port allocation range,預設 3000, 4000」,沒講到限制。試出來的結果是這樣:
[3000, 4000] OK [3100, 4100] OK [4000, 5000] OK [3100, 3200] INVALID [3001, 4000] INVALID
所以range的寬度可能是必須恰好等於 1000,起點沒有限制。所以正確的閃避方式是平移整段ports
supervisor.port.range: [3100, 4100]
Problem Java version [local-2]
文件寫的支援範圍是Java 8/11/17/21,我機器上是 26。實測下來所有功能都正常,唯一的問題是RocksDB的JNI會噴warning
WARNING: java.lang.System::loadLibrary has been called by org.rocksdb.RocksDB WARNING: Restricted methods will be blocked in a future release
現在只是警告,但未來的 JDK 會直接封鎖
Zookeeper 是必要的嗎? [local-3]
是的,對真正的cluster來說沒有免ZK的模式
- 只是要開發、測試 module:用
InProcessCluster,把 Rama 當成 Maven 依賴拉進專案,InProcessCluster.create()會在 process 內模擬一整個叢集,API 跟真叢集完全相同。不需要 ZK、不需要 CLI、不需要任何 daemon。官方建議的開發流程就是用 IPC 開發測試,再用 CLI 部署到真叢集 - 自用的小叢集:ZK 要有,但不需要是額外的機器。內建的
devZookeeper就是一個單機 ZK,跟 Conductor 擠同一台就好。它沒有 HA,ZK 掛了叢集就失去協調能力,自用場景通常還可以接受;不然就是要自己開一個獨立的 Apache ZooKeeper
所以ZK是必要的元件,但不一定需要額外的機器
從別台機器部署 [local-4]
這是我最想確認的使用方式:把叢集跑在別的機器上,然後從筆電下部署指令
client 端的 rama.yaml 只需要一行。我把設定刪到只剩 conductor.host,conductorReady、moduleStatus、deploy --action update 都還是能用
再來我讓 zookeeper.servers 指向一個不存在的host,上面的指令包含deploy在內照樣成功。也就是說CLI client完全不需要管Zookeeper,它只跟Conductor對話,module的jar是上傳給Conductor、再由Conductor散佈出去的
兩個要注意的地方:rama.yaml 這個檔案本身必須存在而且非空,空檔案會得到錯誤訊息 Could not find rama.yaml on classpath;另外client端的release版本必須跟叢集完全一致
所以一組最小的遠端配置是這樣。叢集那台,Conductor、Supervisor、ZK 都在上面執行:
conductor.host: internal: "localhost" external: "10.0.0.1" # cluster 對外的 IP local.dir: "/var/rama" zookeeper.servers: ["localhost"] worker.child.opts: "-Xmx4096m"
Client的設定只需要
conductor.host: "10.0.0.1"
License [local-5]
內建的免費license上限是2 台 Supervisor 節點,Conductor跟Zookeeper不計。用 rama licenseInfo 可以看到 num-nodes: 2,有效期到2117年
所以自用的天花板就是兩台工作機。再往上要跟 RPL 買 license,拿到以後用 rama upsertLicense --licensePath xxx.edn 裝上去
常用指令 [local-6]
# 部署自己的 module rama deploy \ --action launch \ --jar target/app.jar \ --module com.foo.MyModule \ --tasks 64 \ --threads 16 \ --workers 8 \ --replicationFactor 2 # 程式改動之後重新部署 rama deploy --action update \ --jar target/app.jar \ --module com.foo.MyModule rama scaleExecutors --module com.foo.MyModule --threads 90 --workers 30 rama moduleStatus com.foo.MyModule rama destroy --module com.foo.MyModule rama repl --module com.foo.MyModule rama runClj my.ns /path/to.jar rama backup / supportBundle rama shutdownCluster
--tasks 必須是 2 的次方,而且要滿足 tasks >= threads >= workers。這個約束在 deploy 跟 scaleExecutors 都適用