閱讀218 返回首頁    go 技術社區[雲棲]


MyRocks簡介


title: MySQL · 特性分析 · MyRocks簡介

author: 濟天

RocksDB是facebook基於LevelDB實現的,目前為facebook內部大量業務提供服務。經過facebook大量工作,將RocksDB作為MySQL的一個存儲引擎移植到MySQL,稱之為MyRocks。
經過兩年的發展,MyRocks已經比較成熟(RC階段),現已進入了facebook MySQL的主分支了。MyRocks是開源的,參見git
下麵對MyRocks做一個簡單介紹,不涉及源碼。

RocksDB與innodb的比較

  • innodb空間浪費, B tree分裂導致page內有較多空閑,page利用率不高。innodb現有的壓縮效率也不高,壓縮以block為單位,也會造成浪費。

  • 寫入放大:innodb 更新以頁為單位,最壞的情況更新N行會更新N個頁。RocksDB append only方式
    另外,innodb開啟double write也會增加寫入。

  • RocksDB對齊開銷小:SST file (默認2MB)需要對齊,但遠大於4k, RocksDB_block_size(默認4k) 不需要對齊,因此對齊浪費空間較少

  • RocksDB索引前綴相同值壓縮存儲

  • RocksDB占總數據量90%的最底層數據,行內不需要存儲係統列seqid
    (innodb聚簇索引列包含trxid,roll_ptr等信息)

來看看facebook的測試數據

  • 數據空間對比

screenshot

  • QPS

screenshot

  • 寫入放大對比

screenshot

數據字典

數據字段信息保存在System Column Family (System CF) "__system__"中
數據字段信息包括:

  • 表信息,表名和index id的映射
  • 索引信息,索引元數據信息和column family id。column family和index的對應關係 1:N
  • column family,一些標記,比如reverse屬性等
  • binlog信息
  • 統計信息,每個SST file都自帶統計信息(行數、實際大小等),在flush或compaction時更新統計信息,同時統計信息會匯總到數據字典統計信息表中。

以上信息可以通過information_schema查看,如RocksDB_ddl,RocksDB_index_file_map等

記錄格式

RocksDB的行以key value的形式存儲,和innodb類似,記錄格式主鍵和二級索引也有區別

screenshot

事務與鎖

MyRocks也是基於行鎖,鎖信息都保存在內存中。

MyRocks也支持MVCC,MVCC通過快照的方式實現,類似於PostgreSQL。

MyRocks目前隻支持兩種隔離級別,RC和RR。

RR表現和innodb並不一樣,RocksDB 的快照不是在事務開始的時候建立,而是延遲到第一次讀的時候建立.

以下client1 MyRocks返回的是2,innodb返回1

<client 1>                                               <client 2>
CREATE TABLE t1(pk INT PRIMARY KEY);
INSERT INTO t1 VALUES(1);
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
                                                         SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN
                                                         INSERT INTO t1 VALUES(2);
SELECT COUNT(*) FROM t1; // MyRocks返回的是2,innodb返回1

RC表現也不一樣,事務1大更新多行過程中,其他事務也可以更新事務還未更新到的行,事務1再更新時會失敗。

複製

MyRocks也是通過binlog方式複製,由於binlog與RocksDB之間沒有xa,異常crash可能丟數據,所以,MyRocks主備環境建議開啟semi-sync.
由於gap lock支持不健全(僅primary key上支持), 使用statement方式複製會導致不一致,所有MyRocks建議使用行級複製。

備份恢複

支持MySQLdumup邏輯備份

 #內部會執行以下語句
 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
 START TRANSACTION WITH CONSISTENT RocksDB SNAPSHOT;

同時有自動的物理備份工具MyRocks_hotbackup,但還不支持備份innodb; 也不支持增量備份。MyRocks_hotbackup支持流式備份

  MyRocks_hotbackup--user=root --port=3306 --checkpoint_dir=/data/backup --stream=xbstream| ssh$dst‘xbstream–x /data/backup’
  #內部建立硬鏈接方式備份數據SST files,checkpoint多次更新,隻備份新的SST files, 因此WAL日誌很少,恢複時apply log時間很短
  SET GLOBAL RocksDB_create_checkpoint= /path/to/backup

一些優化

  • bloom filter
    bloom filter一般適用於等值查詢
    bloom filter信息存儲在SST files中,大概占用2~3%的空間
    如果大量查詢返回空集建議開啟bloom filter,如果結果每次都在最底層找到,可以設置optimize_filters_for_hits=true關閉bloom filter以節省空間。

  • 數據加載
    數據加載時可以忽略唯一性約束檢查,分段自動提交,停寫wal等。
    以下是推薦的數據加載時的參數配置

    rocksdb_skip_unique_check=1
    rocksdb_commit_in_the_middle=1
    rocksdb_write_disable_wal=1
    rocksdb_max_background_flushes=40
    rocksdb_max_background_compactions=40
    rocksdb_default_cf_options=(in addition to existing parameters); write_buffer_size=128m;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;memtable=vector:1024
    rocksdb_override_cf_options=(in addition to existing parameters);__system__={memtable=skip_list:16}
    
  • Reverse column families
    MyRocks擅長正向掃描,為了提高逆向掃描(ORDER BY DESC)的性能,MyRocks支持了Reverse column families。 在建表可以指定column family的reverse屬性。

  • singleDelete
    如果key不會重複put, delete操作可以直接刪除put,而不是標記刪除。singleDelete可以提高查詢效率。

一些限製

MyRocks目前有以下一些限製

  • 不支持分區表,Online ddl,外鍵,全文索引,空間索引,表空間transport

  • gap lock支持不健全(僅primary key上支持), 使用statement方式複製會導致不一致

  • 不支持select … in share mode

  • 大小寫敏感,不支持*_bin collation

  • binlog與RocksDB之間沒有xa,異常crash可能丟數據。所以,MyRocks一般開啟semi-sync.

  • 不支持savepoint

  • order by 不比較慢

  • 不支持MRR

  • 暫不支持O_DIRECT

  • innodb和RocksDB混合使用還不穩定

最後更新:2017-06-05 11:33:48

  上一篇:go  釘釘 ISV 應用開發的一些心得
  下一篇:go  velocity的html語義轉換