高併發系統設計九-NoSQL補充數據庫

NoSQL補充數據庫

  • Redis、LevelDB KV存儲,相比傳統的數據庫優勢是極高的讀寫性能,一般對性能比較高的要求的場合會使用
  • Hbase、Cassandra 列式存儲數據庫。適用於一些離線數據統計的場景
  • MongoDB、CouchDB 文檔型數據庫。Schema Free(模式自由),數據表中的字段可以任意擴展,比如電商系統中商品有非常多的字段,而且每個字段不同

實際場景中發現,SQL 語句的強大的查詢功能以及傳統數據庫事務和靈活的索引等功能,NoSQL 只能作爲一些場景的補充。

1、 提升性能

在性能方面,NoSQL 數據庫使用一些算法將對磁盤的隨機寫轉換成順序寫,提升了寫的性能

1.1、數據庫

數據庫系統大多使用的是傳統機械磁盤,訪問方式有兩種:隨機IO、順序IO。隨機 IO 需要花費時間做磁盤尋道,讀寫效率比順序IO 小兩到三個數量級。

以 MySQL 的 InnoDB 存儲引擎來說,更新 binlog、redolog、undolog 都是在做順序 IO,而更新 datafile 和索引文件則是在做隨機 IO,而爲了減少隨機 IO 的發生,關係數據庫已經做了很多的優化,比如說寫入時先寫入內存,然後批量刷新到磁盤上,但是隨機 IO 還是會發生。


索引在 InnoDB 引擎中是以 B+ 樹方式來組織的,而 MySQL 主鍵是聚簇索引(一種索引類型,數據與索引數據放在一起),既然數據和索引數據放在一起,那麼在數據插入或者更新的時候,我們需要找到要插入的位置,再把數據寫到特定的位置上,這就產生了隨機的 IO。而且一旦發生了頁分裂,就不可避免會做數據的移動,也會極大地損耗寫入性能。

1.2、NoSQL 如何解決

很多 NoSQL 數據庫都在使用的基於 LSM 樹的存儲引擎

LSM 樹(Log-Structured Merge Tree)犧牲了一定的讀性能來換取寫入數據的高性能,Hbase、Cassandra、LevelDB 都是用這種算法作爲存儲的引擎

  • 數據先寫入到 MemTable 的內存結構中,MemTable中數據是按照寫入的 Key 來排序的。爲了防止 MemTable 數據丟失,會通過 Write Ahead Log 的方式將數據備份在磁盤上。
  • MemTable 在累積到一定規模時,它會被刷新生成一個新的文件 SSTable(Sorted String Table)。當 SSTable 達到一定數量時,將 SSTable 合併,減少文件的數量。因爲 SSTable 是有序的,所以合併速度也是很快的
  • 從 LSM 讀取數據時,先從 MemTable中查,如果沒有,再從 SSTable中查。因爲存儲的數據都是有序的,所以查找效率也是很高的,只是因爲數據被拆分成多個 SSTable,所以讀取的效率會低於 B+ 樹索引。

2、 搜索功能

在某些場景下,比如全文搜索功能,關係型數據庫並不能高效地支持,需要 NoSQL 數據庫的支持

在模糊查詢查詢中,一旦沒有使用索引就會掃描全表的數據,一般會使用開源組件Elasticsearch 來支持搜索的請求,它本身是基於“倒排索引”來實現的。

倒排索引是指將記錄中的某些列做分詞,然後形成的分詞與記錄 ID 之間的映射關係

Elasticsearch 作爲一種常見的 NoSQL 數據庫,就以倒排索引作爲核心技術原理,爲你提供了分佈式的全文搜索服務。

3、提升擴展性

在擴展性方面,NoSQL 數據庫天生支持分佈式,支持數據冗餘和數據分片的特性。

MongoDB 三個擴展性方面的特性

  • Replica,也叫做副本集,你可以理解爲主從分離,也就是通過將數據拷貝成多份來保證當主掛掉後數據不會丟失。同時呢,Replica 還可以分擔讀請求。Replica 中有主節點來承擔寫請求,並且把數據變動記錄到 oplog 裏(類似於 binlog);從節點接收到 oplog 後就會修改自身的數據以保持和主節點的一致。一旦主節點掛掉,MongoDB 會從從節點中選取一個節點成爲主節點,可以繼續提供寫數據服務
  • Shard,也叫做分片,你可以理解爲分庫分表,即將數據按照某種規則拆分成多份,存儲在不同的機器上。MongoDB 的 Sharding 特性一般需要三個角色來支持,一個是 Shard Server,它是實際存儲數據的節點,是一個獨立的 Mongod 進程;二是 Config Server,也是一組 Mongod 進程,主要存儲一些元信息,比如說哪些分片存儲了哪些數據等;最後是 Route Server,它不實際存儲數據,僅僅作爲路由使用,它從 Config Server 中獲取元信息後,將請求路由到正確的 Shard Server 中
  • 負載均衡,就是當 MongoDB 發現 Shard 之間數據分佈不均勻,會啓動 Balancer 進程對數據做重新的分配,最終讓不同 Shard Server 的數據可以儘量的均衡。當我們的 Shard Server 存儲空間不足需要擴容時,數據會自動被移動到新的 Shard Server 上,減少了數據遷移和驗證的成本。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章