我們一起聊聊分布式數(shù)據(jù)服務
目標
數(shù)據(jù)存儲資源是系統(tǒng)中最重要的組成部分,數(shù)據(jù)即一切,尤其分布式領域,主要關(guān)注以下幾點:
- 高可用性,當遇到網(wǎng)絡或者系統(tǒng)故障時,系統(tǒng)仍然保持可用
- 高擴展,當數(shù)據(jù)規(guī)模變大時,數(shù)據(jù)存儲系統(tǒng)能夠自動適應這種變化
- 高性能,當數(shù)據(jù)規(guī)模和訪問規(guī)模變大時,性能不受大的影響
- 成本,通過成本反映出系統(tǒng)設計是合理的
- 安全,遇到各種系統(tǒng)和人為故障時,數(shù)據(jù)不丟失
MySQL
MySQL是OLTP關(guān)系型數(shù)據(jù)庫,支持ACID事務,是最主要的存儲系統(tǒng),目前使用的版本是5.7。
MySQL本身不是分布式系統(tǒng),其支持的數(shù)據(jù)復制技術(shù),本質(zhì)上是為了數(shù)據(jù)容災使用,但目前基于主從復制進行讀寫分離,減少單機的讀壓力。
MySQL服務如果托管在阿里云,可以使用高可用版本,秒級的主從切換,基于云盤的磁盤擴容技術(shù),能夠快速復制一個只讀節(jié)點,減少了很多自建MySQL遇到的各種問題,另外其還提供了很多額外的功能,比如索引分析、SQL審查、慢查詢分析、動態(tài)擴容。
雖然云托管RDS,但本質(zhì)上還是MySQL,仍然會遇到很多問題,比如:
- 數(shù)據(jù)存儲不支持分片,只能通過分庫分表的方式進行橫向擴展,目前應用層也不支持分庫分表的路由,即使分表,拆分表的時候還是會遇到很多問題
- 如果表設計和索引設計不合理,大量的更新,仍然會遇到主從延遲的問題,從應用層面是很難徹底解決的
- 阿里云RDS只支持一個負載均衡主從分離,所以后臺、隊列應用使用360 Atlas讀寫分離服務,目前是一個單點,且也會影響讀寫性能。
- MySQL應用規(guī)范目前還沒有建立,比如什么樣的應用應該選擇MySQL,使用MySQL很大程度是為了事務,如果沒有事務的場景是否可以選擇其他的數(shù)據(jù)庫?
- 阿里云官方提到,單表記錄數(shù)超過500w,性能會極具下降
- DDL操作,尤其對于大表操作,會引起很大的同步延遲問題
云托管的RDS本質(zhì)上還是基于ECS+云盤搭建的,數(shù)據(jù)的增長、備份、性能、遷移、升級、只讀實例、磁盤容量、Binlog延遲還是會顯露出來。
那未來如何?其實云廠商也在探索,提出了云原生數(shù)據(jù)庫、云原生分布式數(shù)據(jù)的概念,比如阿里云的PolarDB、PolarDB-X。
云原生數(shù)據(jù)庫關(guān)注成本、性能、在線業(yè)務擴展、數(shù)據(jù)安全,它的核心技術(shù)包括計算和存儲分離,物理復制Binlog行復制模式,共享存儲設備,存儲之間通過RDMA高速網(wǎng)絡協(xié)議傳輸,同時PolarDB-X支持分區(qū)模式,解決了分庫分表的問題。
經(jīng)過這些創(chuàng)新,傳統(tǒng)MySQL的弊端被解決了,比如同步延遲、備份、成本、分庫分表、性能。
未來,可以將核心數(shù)據(jù)庫遷移至云原生數(shù)據(jù)庫,保障核心業(yè)務的穩(wěn)定性和擴展性,而對于非OLTP業(yè)務可以選擇其他數(shù)據(jù)庫,且制定MySQL應用規(guī)范,明確哪些業(yè)務模式使用MySQL,索引正確設計、容量規(guī)劃、SQL語句使用規(guī)范等等。
Redis
Redis是K/V數(shù)據(jù)庫,它基于單線程、內(nèi)存操作,所以性能非常高。另外支持豐富的數(shù)據(jù)結(jié)構(gòu),比如字符串、Hash、List、集合,應用場景非常廣泛。
它通過AOF和RDB保障數(shù)據(jù)持久化,通過復制技術(shù)進行數(shù)據(jù)備份,也支持通過哨兵和分區(qū)提供高可用性和容量伸縮,通過LUA腳本支持多條命令的事務操作。
Redis雖然是一個單機系統(tǒng),但通過復制、集群技術(shù)也可以認為是一個分布式存儲系統(tǒng),目前西五街在大量使用,主要分為三類應用:
- 存儲,比如用戶積分、文章數(shù)等數(shù)據(jù),這些數(shù)據(jù)不能丟
- 緩存,比如用戶文章列表數(shù)據(jù),需要考慮緩存穿透和雪崩等問題
- 消息隊列,目前逐步替換為Kafka等純消息系統(tǒng)
阿里云云托管Redis社區(qū)版5.0服務集群版。
在應用設計上存在以下幾個問題:
- 存儲和緩存混合使用,無法拆分,對于容量估算不透明
- 應用模式上,沒有很好的規(guī)范,比如緩存更新機制標準、統(tǒng)一Lib應用包
通過阿里云Redis提供的部署架構(gòu),可以很好的理解它的應用場景:
- 標準版-雙副本:服務可靠,數(shù)據(jù)可靠,比較標準的使用模式,不管是存儲還是緩存服務都可用
- 集群版:通過代理模式和分片可以構(gòu)建出一個可伸縮的集群模式,解決Redis自身單線程瓶頸,滿足大容量、高性能的業(yè)務需求,而且副本集主要做恢復用,很適合存儲場景,不存在同步延遲的問題
- 讀寫分離架構(gòu):對于不關(guān)注同步延時的問題,比如緩存場景,可以選擇這種模式,當容量不夠的適合,通過客戶端的一致性Hash技術(shù)擴容多個Redis實例就可以
后續(xù)確定Redis使用規(guī)范,拆分存儲和緩存場景,基于統(tǒng)一Lib包,就能解決大部分問題。
Elasticseach
Elasticseach是一個近實時的分布式搜索引擎和分析引擎。
作為一個搜索引擎,目前在開源領域已經(jīng)是排名第一的數(shù)據(jù)庫了;基于倒排索引,具有很強的檢索能力,所以不管是應用還是在大數(shù)據(jù)領域,它都是一個非常通用的分析引擎。
近實時表示Elasticseach應用場景必須要有所了解,它不支持ACID,所以無法是一個OLTP數(shù)據(jù)庫,但使用壓力小了很多,在做策略分析、后臺應用、即時查詢上有很廣泛的場景。
作為一個分布式應用,通過副本集機制解決高可用的問題,能夠解決單機故障的問題,但如果數(shù)據(jù)被誤刪除,還是需要有備份機制,比如Elasticseach的快照機制。
副本集的同步最終達到一致性,為了寫入性能,也可以配置主節(jié)點寫入完成即返回給客戶端。
在容量可擴展方面,可以采用分片機制解決容量橫向伸縮的問題,將數(shù)據(jù)分到不同節(jié)點的不同分片上,如果要調(diào)整分片,需要reindex。
在性能方面,通過多副本集節(jié)點分擔查詢壓力。也可以使用專門的Transport節(jié)點分擔date Node節(jié)點的壓力,將分片查詢,副本查詢等路由和合并動作的結(jié)果匯總起來。
Elasticseach是ELK解決方案的一部分,其還包括很多服務,包括Filebat,Kibana,Logstash,在大數(shù)據(jù)領域也是很好的一個方向。
Elasticseach是在ELK上搭建的三節(jié)點服務,由于規(guī)模問題,目前也很少使用分片技術(shù)。核心是文章大寬表,用戶大寬表。
結(jié)合了搜索場景和分析場景,通過Binlog+Canal+Kafka+Go服務將MySQL多個表匯總到一個大寬表,主要是文章信息的大寬表,一方面是滿足搜索場景,另外滿足策略和應用場景。
現(xiàn)在大寬表的應用模式非常多,基于Free Schema模式,查詢模式非常靈活,通過訂閱方式同步數(shù)據(jù),也減輕了應用層的負擔,數(shù)據(jù)正確性有很大的保障。
未來,對于Elasticseach的應用,一方面要加強性能調(diào)優(yōu),比如分片數(shù)據(jù)的不均勻,查詢性能的優(yōu)化,同時要提升可維護性,比如挖掘reindex、alias等功能,充分理解Elasticseach。
而在國內(nèi)的云廠商中,都沒有對Elasticseach做太大的升級,基本上就是將Elasticseach服務托管到云中。
Kakfa
Kakfa是一個分布式的高吞吐消息隊列,訂閱/消費模式追求的是高性能,而非存儲容量。但其日志本身具有重放功能,也可以理解為一個分布式存儲系統(tǒng)。
Kafka的核心功能包括:解耦、消峰、緩存,應用場景極為廣泛,是系統(tǒng)不可缺少的一個組件。
作為分布式系統(tǒng),它也有副本和分區(qū)機制,從而保障高可用和高吞吐。通過segment順序?qū)?,保障了寫性能非常高,而基于消費組組的概念,消費者吞吐能力也能橫向擴展。同時每個broker都能負責查詢,提升了吞吐能力
Kafka基于Zookeeper做很多分布式管理功能,包括Leader選舉,負載均衡,Meta存儲。
目前Kafka三節(jié)點集群是通過ECS自行搭建的,運行近一年,服務相對穩(wěn)定,可維護性也較好,沒有太多的管理工作,很多核心服務都已經(jīng)使用了Kafka隊列,后續(xù)原有基于Redis的隊列也可以盡快遷移。
MongoDB
MongoDB是一個分布式的文檔數(shù)據(jù)庫,其目標是一個支持ACID事務的分布式數(shù)據(jù)庫,因為是面向文檔,所以模式非常靈活,結(jié)構(gòu)松散,使用場景很規(guī)范,相比MySQL,其二進制的存儲模式,壓縮比非常高,存儲成本會大幅減少,同時基于WiredTiger引擎,能夠創(chuàng)建各種類型的索引,甚至子文檔也能創(chuàng)建索引,從而提升查詢性能
MongoDB通過oplog技術(shù)支持副本集,也支持分區(qū),分區(qū)鍵可以自定義,因為有了分區(qū),所以額外有了mongos路由服務器,config服務器,mongos路由服務器通過查詢config服務器,向節(jié)點和分區(qū)發(fā)送服務。
MongoDB將一致性和性能訴求交給了客戶端,通過read concern、write concern、read perference技術(shù)提供多種靈活性,比如你要求強一致性,那么就采用majority,你要求數(shù)據(jù)永遠不丟失就配置journal為真。
MongoDB 4.0和MongoDB 4.2支持多文檔的事務,分別支持復制集、分區(qū)維度的事務性,但使用和理解非常復雜,可能是分布式系統(tǒng)中最難學習的部分。
這樣說明,不用刻意使用事務,對MongoDB進行良好的建模,做OLTP關(guān)系數(shù)據(jù)的補充,其在性能、成本、高可用、伸縮性方面是有優(yōu)勢的。其實在MySQL中,目前我們也很少使用跨表,跨語句的事務,所以不要太迷信事務,選擇好應用場景。
除了查詢,MongoDB也支持各種聚合操作,在分析領域也很有廣泛的使用場景,這一點和Elasticseach很類似。
目前MongoDB三節(jié)點集群是通過ECS自行搭建的,存儲規(guī)模較小,使用場景較少。
對比MySQL和Elasticseach,MongoDB還是有很廣泛的應用場景,比如分析場景,對事務要求不高的場景,數(shù)據(jù)增長比較大的場景(比如私信數(shù)據(jù)),業(yè)務模式比較靈活的場景(比如各種條件的查詢,聚合操作)。
不過和Elasticseach一樣,各大云廠商一樣,只是將這個服務托管到云,并沒有做太多的優(yōu)化。