分布式全局ID生成器作為分布式架構中重要的組成部分,在高並發場景下承載着分擔數據庫寫瓶頸的壓力。
之前實現過PHP+Swoole版,性能和穩定性在生產環境下運行良好。這次使用Java進行重寫,目前測試情況表現還不錯,下面我簡要介紹下java版的項目情況。
技術架構:Netty + Zookeeper + Redis Protocol
- Netty:是一個基於NIO的客戶、服務端編程框架(類似於swoole)。使用netty作為服務端應用接收客戶端請求,對Redis協議數據進行編解碼,響應redis客戶端請求。
- Zookeeper:主要兩個作用。一是生成器服務每個節點需預先定義唯一serverId,並注冊到zk,由zk統一管理集群節點連接狀態;二是自增序列sequenceId可交由zk管理,集群中的自增序列在毫秒級內共用一個值,不過這涉及到共享鎖的資源競爭和網絡傳輸,性能很差,默認沒開啟,下面有具體的壓測情況。
下面是通過redis-benchmark壓測工具在本機對php版、java版、及原生redis-server進行壓測的QPS數據(使用默認並發50)
PHP版測試命令:redis-benchmark -h 127.0.0.1 -p 9501 -t get -n 200000 -q

Java版測試命令:redis-benchmark -h 127.0.0.1 -p 3308 -t get -n 200000 -q

自增序列sequenceId交由zk管理后性能堪憂~測試命令:redis-benchmark -h 127.0.0.1 -p 9300 -t get -n 2000 -q

原生redis-server測試命令:redis-benchmark -h 127.0.0.1 -p 6379 -t get -n 200000 -q

從壓測數據上看,Java版相對於PHP版有接近一倍的性能提升,已經接近c語言編寫的redis server。
僅支持get命令,key格式固定如下:
172.19.19.233:9303>
get id.1
4612394007866114075
172.19.19.233:9303>
get id.1.3
4612394014021255195,4612394014021271579,4612394014021287963
172.19.19.233:9303>
get parse.4612393968093626395
[1, 2018:11:16 15:15:02.707, 0, 1, 11]
命令解釋:
get id.1 獲取單個id,1為業務id,支持0-1023
get id.1.3 一次性獲取3個id,1為業務id
get parse.4612393968093626395 解析id信息,反解出時間戳,業務id,集群節點id,自增id信息
敲其它命令會返回error信息。