梅巧玲,楊立鵬,樊春美,馮 炎
(中國鐵道科學研究院集團有限公司 電子計算技術研究所, 北京 100081)
在鐵路12306售票系統中,常用聯系人集群是售票主流程中的重要環節,也是用戶能否購票成功的關鍵。常用聯系人集群應用分布式內存數據庫技術,每個集群由若干臺服務器組成,每臺服務器上數百計的內存全部被該進程占用,存放12306售票系統所有用戶大約幾十億條的常用聯系人數據。數據庫為雙表結構,極大地提高了查詢效率,但由于現階段產品本身的局限性,兩個表之間的一致性無法得到保證,當常用聯系人集群持久化的文件不可用時,需要從數據庫重新導出數據再導入集群,進行創建索引等操作,進行一次全量數據的導入和創建索引要花費幾十個小時,給維護工作帶來很大困擾。
文章在常用聯系人集群原有架構的基礎上,將GEMFIRE內存數據庫產品替換為分布式內存服務軟件Redis,新架構不僅具備查詢效率高等優點,還解決了數據一致性、維護便捷、故障快速恢復等問題。
常用聯系人集群新架構如圖1所示。整個系統采用雙中心的模式,兩個中心共同承擔所有互聯網流量,形成雙活態勢并且互為應急,任何一個中心發生故障,業務均能切換到另一個中心工作,實現應用級容災。每個中心的常用聯系人集群主要由查詢服務和數據同步兩個功能組成,查詢服務由常用聯系人微服務集群、分布式內存數據服務和Redis-Server組成;數據同步主要由數據庫、消息服務器Rabbit MQServer和消費端組成。

圖1 常用聯系人集群新架構
常用聯系人微服務是由高性能Web服務Nginx和腳本語言lua組合而成的應用服務,提供聯系人操作的API查詢服務。常用聯系人微服務是無狀態的,支持水平擴展,支持集群之間的流量分配和集群切換,支持按照百分比進行多集群流量分配,能夠實時查看各集群的使用狀態和流量配置,每一個服務進程都有對應的監控腳本,發現問題時先自動重啟,重啟失敗后發送消息到報警中心。
分布式內存數據服務是客戶端連接Redis的代理服務, 使用go語言開發,支持多線程,實現了Redis協議,支持原生的大部分命令。對于同一個業務集群而言,可以同時部署多個分布式內存數據服務實例,不同分布式內存數據服務之間由運維管理平臺保證狀態同步。分布式內存數據服務還負責數據的預先分片,獲取請求校驗命令合法后,根據操作的key值HASH到1 024個slot相應的后端Redis服務器進行執行,分布式內存數據服務跟后端Redis的一個數據庫TCP連接,通過pipeline模式與Redis交互。它將業務系統和Redis存儲剝離開,實現了業務分離,同時降低了系統維護成本。
Redis是一個由Salvatore Sanfilippo寫的keyvalue存儲系統。Redis提供了一些豐富的數據類型,包括 lists、sets、ordered sets、hashes等。
Redis數據庫所有的數據都存儲在內存中,它的讀寫操作在1 s內超過10萬個鍵值。同時Redis也提供了RDB、AOF持久化的支持,在不影響繼續提供服務的情況下,將內存中的數據異步寫入硬盤中,避免數據意外丟失。RDB持久化是通過將服務器某個時間點上的數據庫狀態保存到一個RDB文件中,Redis服務器可以用它來還原數據庫狀態。AOF持久化通過保存Redis服務器執行的命令來記錄數據庫狀態,被寫入AOF文件的所有命令都是以Redis命令請求協議格式保存的,Redis命令請求協議保存為純文本格式。
Redis中的事務是一組命令的集合。事務同命令一樣都是Redis的最小執行單位,一個事務中的命令要么都執行,要么都不執行。一個事務從開始到結束通常會經過事務開始、命令入隊、事務執行3個階段。每個Redis客戶端都有自己的事務狀態,保存在mstate屬性中。每一個事務狀態包含一個事務隊列以及已入隊命令的計數器,事務隊列是一個數組,數組中的每個元素保存了已入隊命令的相關信息,包含指向命令實現函數的指針、命令的參數,以及參數的數量。
消息隊列(MQ,Message Queue)適用于異構的系統之間做間接的消息傳遞,異構系統兩端程序之間通過在消息包中發送數據進行通信,兩端程序實際上并不會直接進行通信。消息隊列作為一種中間件技術,對它的使用忽略了接收和發送應用程序必須同時執行的要求,達到了異構系統間的異步通信,如果消息隊列服務器的性能足夠好,那么系統間的消息可以近乎實時的傳遞,達到“準同步通信”的效果。
RabbitMQ更適合于穩定高效的企業級開發,實現了Broker中心構架,消息在發送給客戶端之前,必須先要在中心隊列排隊。RabbitMQ對路由、負載均衡、數據持久化都有很好的支持。RabbitMQ采用Erlang語言編寫,使用AMQP協議的高效開源消息隊列系統,得到廣泛的應用。從框架角度來說,RabbitMQ分為客戶端和服務器端兩部分:客戶端可以是消息產生者(Producer)和消息消費者(Consumer);服務器端就是RabbitMQ消息隊列服務器本身[6]。
消息端從消息隊列中接收到消息后,經過分析處理寫入集群中,然后返回給MQServer服務器ack標識,表示消費成功,繼續接收下一條消息,以此類推。
為了能夠充分體現常用聯系人集群新架構可提供高并發運算處理能力,從并發性能和高可用性兩方面對集群進行測試。在測試環境中,所有測試主機均配有512 G內存,2×10核64 bit處理器,千兆以太網交換模塊等環境,所有測試主機上只運行該應用,沒有其他應用共享,最大程度上保證測試環境的單一,避免外界因素對環境的影響。
1.5.1 性能測試
常用聯系人集群的性能測試主要包括寫入和讀取兩方面測試。集群有8臺服務器,每臺服務器上有4個master實例和4個slave實例,測試場景如下:
測試場景1:8臺服務器同時統計當前 Redis 集群數據詳情,所有服務器讀取速度可達 650萬次/s,如圖2所示。

圖2 測試場景1數據圖
測試場景2:單臺服務器統計當前 Redis 集群數據,讀取速度可達 270萬次/s,如圖3所示。

圖3 測試場景2數據圖
測試場景3:8臺服務器同時導入數據,寫入速度可達 20萬次/s,如圖4所示。

圖4 測試場景3數據圖
通過以上測試結果,常用聯系人集群在讀寫性能上較原架構持平,Redis 服務端網絡帶寬最大占用 500 Mbit左右,Redis 服務端 CPU 使用率不超過45%,系統運行平穩。
1.5.2 高可用測試
常用聯系人集群在系統性能和高可用性上,可以實現不停機、不停服務地動態增加或減少服務節點,系統能保持極高的穩定性,當少量節點發生崩潰等故障退出服務時,集群中的其他節點可以立即接管服務,且沒有數據損失,測試結果如表1所示。

表1 測試結果
常用聯系人的增加、更改和刪除這些寫操作都是在關系型數據庫中,從關系型數據庫到Redis集群中,中間需要經過3個環節,因此兩個數據中心之間數據的一致性尤為重要。首先系統將同步過程中的SQL語句記錄下來,考慮到系統的性能和壓力,實時對每分鐘內同步的30%比例的用戶名進行檢測,調用數據庫和Redis的接口查看數據的一致性,對于比對錯誤的數據調用同步接口進行實時同步。其次,除了準實時比對,在互聯網天窗時間,對每個數據庫分庫的用戶總量和Redis中的數據總量進行宏觀比對。通過準實時比對和宏觀比對,對數據的一致性提供了更全面的保障。
Redis的主從復制功能非常強大,一個master可以擁有多個slave,而一個slave又可以擁有多個slave,形成了強大的多級服務器集群架構。主從復制不會阻塞master,也就是說當一個或多個slave與master進行初次同步數據時,master可以繼續處理client發來的請求。相反slave在初次同步數據時則會阻塞不能處理client的請求。當設置好slave服務器后,slave會建立和master的連接,然后發送SYNC命令。無論是第一次同步建立的連接還是連接斷開后的重新連接,master都會啟動一個后臺進程,將數據庫快照保存到RDB文件中,同時master主進程會開始收集新的寫命令并緩存在backlog中。master主進程發送RDB文件給slave,slave將文件保存到磁盤上加載到內存中,master將緩存在backlog中的寫命令通過開始建立的連接發送給slave,達到主從數據的一致性。當master和slave的連接斷開時slave可以自動重新建立連接。如果master同時收到多個 slave發來的同步連接命令,只會使用啟動一個進程來寫數據庫鏡像,然后發送給所有slave[2]。Redis主從復制流程圖如圖5所示。

圖5 Redis主從復制流程圖
在運維管理控制臺中可以進行微服務、內存數據服務和Redis 組實例的添加、刪除,以及數據遷移等操作。在集群狀態發生改變時,維護集群下所有分布式內存數據服務狀態的一致性,圖形化界面監控管理集群,能夠查看每秒查詢次數QPS(query per second,內存數據大小,訪問時間RT等,如圖6所示。
實時監控管理對集群中每個服務節點的CPU、內存、磁盤空間大小、服務狀態,以及每個集群的流量分配和相應時間RT進行檢測,報警機制分為一般、嚴重和災難3個級別。對于不同級別的報警會以不同的形式,發送給不同的人群。監控界面如圖7所示。

圖6 監控查詢界面圖

圖7 監控界面
集群之間的切換是使用Zookeeper來實現的,用來存放數據路由表和分布式內存數據服務節點的元信息,運維管理平臺發起的命令都會通過ZooKeeper同步到各個存活的分布式內存數據服務節點上。提供Namespace 概念,不同集群會按照不同 product name進行組織。
在鐵路互聯網售票系統面臨的并發和存儲雙重壓力下,通過對常用聯系人集群新架構進行性能和高可用測試,證明了采用分布式數據處理技術的新架構可以滿足高并發需求和海量數據存儲需求,降低了單臺服務器對整個集群的影響范圍,縮短了系統維護時間。常用聯系人集群新架構已上線,系統運行平穩,實現了原有架構到新架構的平穩遷移。
