精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

萬字長(zhǎng)文,深入淺出講解分布式數(shù)據(jù)庫TiDB架構(gòu)設(shè)計(jì)

原創(chuàng) 精選
數(shù)據(jù)庫
TiDB 是一款開源分布式關(guān)系型數(shù)據(jù)庫,同時(shí)支持 在線事務(wù)處理(OLTP) 與 在線分析處理(OLAP) 的混合型(Hybrid Transactional and Analytical Processing, HTAP) 分布式數(shù)據(jù)庫,具備水平擴(kuò)容或縮容、金融級(jí)高可用、實(shí)時(shí) HTAP、Kubernetes 云原生的分布式數(shù)據(jù)庫、兼容 MySQL 5.7 協(xié)議和 MySQL 生態(tài)等重要特性。

TiDB概述

TiDB 是一款開源 分布式關(guān)系型數(shù)據(jù)庫,同時(shí)支持 在線事務(wù)處理(OLTP) 與 在線分析處理(OLAP) 的混合型(Hybrid Transactional and Analytical Processing, HTAP) 分布式數(shù)據(jù)庫,具備水平擴(kuò)容或縮容、金融級(jí)高可用、實(shí)時(shí) HTAP、Kubernetes 云原生的分布式數(shù)據(jù)庫、兼容 MySQL 5.7 協(xié)議和 MySQL 生態(tài)等重要特性,支持在本地和云上部署。

與傳統(tǒng)的單機(jī) MySQL 數(shù)據(jù)庫相比,TiDB 具有以下優(yōu)勢(shì):

  • 分布式架構(gòu): 純分布式架構(gòu),擁有良好的擴(kuò)展性,支持彈性的擴(kuò)縮容
  • 兼容MySQL: 支持 SQL,對(duì)外暴露 MySQL 的網(wǎng)絡(luò)協(xié)議,并兼容大多數(shù) MySQL 的語法,在大多數(shù)場(chǎng)景下可以直接替換 MySQL
  • 高可用部署: 默認(rèn)支持高可用,在少數(shù)副本失效的情況下,數(shù)據(jù)庫本身能夠自動(dòng)進(jìn)行數(shù)據(jù)修復(fù)和故障轉(zhuǎn)移,對(duì)業(yè)務(wù)透明
  • 支持強(qiáng)一致性: 符合CAP理論的CP,支持 ACID 事務(wù),對(duì)于一些有強(qiáng)一致需求的場(chǎng)景友好,例如:銀行轉(zhuǎn)賬
  • 豐富的開源生態(tài)鏈: 具有豐富的工具鏈生態(tài),覆蓋數(shù)據(jù)遷移、同步、備份等多種場(chǎng)景

TiDB組件

在內(nèi)核設(shè)計(jì)上,TiDB 分布式數(shù)據(jù)庫將整體架構(gòu)拆分成了多個(gè)模塊,各模塊之間互相通信,組成完整的 TiDB 系統(tǒng)。對(duì)應(yīng)的架構(gòu)圖如下:

計(jì)算引擎層:TiDB/TiSpark

OLTP計(jì)算引擎TiDB

TiDB Server 主要用于 OLTP 業(yè)務(wù),屬于 SQL 層,對(duì)外暴露 MySQL 協(xié)議的連接 endpoint,負(fù)責(zé)接受客戶端的連接,執(zhí)行 SQL 解析和優(yōu)化,最終生成分布式執(zhí)行計(jì)劃。

TiDB 層本身是 無狀態(tài)的,實(shí)踐中可以啟動(dòng)多個(gè) TiDB 實(shí)例,通過 負(fù)載均衡組件(如 LVS、HAProxy 或 F5)對(duì)外提供統(tǒng)一的接入地址,客戶端的連接可以均勻地分?jǐn)傇诙鄠€(gè) TiDB 實(shí)例上,以達(dá)到 負(fù)載均衡 的效果。

TiDB Server 本身并不存儲(chǔ)數(shù)據(jù),只是解析 SQL,將實(shí)際的數(shù)據(jù)讀取請(qǐng)求轉(zhuǎn)發(fā)給底層的存儲(chǔ)節(jié)點(diǎn) TiKV(或 TiFlash)。

OLAP計(jì)算引擎TiSpark

TiSpark 作為 TiDB 中解決用戶復(fù)雜 OLAP 需求的主要組件,它將 Spark SQL 直接運(yùn)行在 分布式鍵值對(duì)存儲(chǔ)層 TiKV 上,同時(shí)融合 TiKV 分布式集群的優(yōu)勢(shì),并融入 大數(shù)據(jù)社區(qū)生態(tài)。至此,TiDB 可以通過一套系統(tǒng),同時(shí)支持 OLTP 與 OLAP,免除用戶數(shù)據(jù)同步的煩惱。

TiFlash 和 TiSpark 都允許使用多個(gè)主機(jī)在 OLTP 數(shù)據(jù)上執(zhí)行 OLAP 查詢。TiFlash 是列式存儲(chǔ),它提供了更高效的分析查詢。TiFlash 和 TiSpark 之間的關(guān)系,可類比于 Clickhouse 和 Spark。

分布式協(xié)調(diào)層:PD

PD (Placement Driver) 是整個(gè) TiDB 集群的 元信息管理模塊,負(fù)責(zé)存儲(chǔ)每個(gè) TiKV 節(jié)點(diǎn)實(shí)時(shí)的數(shù)據(jù)分布情況和集群的整體拓?fù)浣Y(jié)構(gòu),提供 TiDB Dashboard 管控界面,并為分布式事務(wù)分配事務(wù) ID。

PD 不僅存儲(chǔ)集群元信息,同時(shí)還會(huì)根據(jù) TiKV 節(jié)點(diǎn)實(shí)時(shí)上報(bào)的 數(shù)據(jù)分布狀態(tài),下發(fā)數(shù)據(jù)調(diào)度命令給具體的 TiKV 節(jié)點(diǎn),可以說是 整個(gè)集群的“大腦” 。

此外,PD 本身也是由至少 3 個(gè)節(jié)點(diǎn)構(gòu)成,擁有高可用的能力。建議部署奇數(shù)個(gè) PD 節(jié)點(diǎn)。

存儲(chǔ)引擎層:TiKV/TiFlash

行存儲(chǔ)TiKV

用于存儲(chǔ) OLTP 數(shù)據(jù),采用 行存儲(chǔ)格式,支持 事務(wù)機(jī)制,TiKV 本身是一個(gè) 分布式的 Key-Value 存儲(chǔ)引擎。

存儲(chǔ)數(shù)據(jù)的基本單位是 Region,每個(gè) Region 負(fù)責(zé)存儲(chǔ)一個(gè) Key Range(從 StartKey 到 EndKey 的左閉右開區(qū)間)的數(shù)據(jù),每個(gè) TiKV 節(jié)點(diǎn)會(huì)負(fù)責(zé)多個(gè) Region。

  • TiKV 的 API 在 KV 鍵值對(duì)層面提供對(duì)分布式事務(wù)支持,默認(rèn)提供了 SI (Snapshot Isolation) 的隔離級(jí)別。
  • TiDB 的 SQL 層做完 SQL 解析后,會(huì)將 SQL 的執(zhí)行計(jì)劃轉(zhuǎn)換為對(duì) TiKV API 的實(shí)際調(diào)用。
  • TiKV 支持高可用和自動(dòng)故障轉(zhuǎn)移,所有數(shù)據(jù)都會(huì)自動(dòng)維護(hù)多副本(默認(rèn)為三副本)。

列存儲(chǔ)TiFlash

用于存儲(chǔ) OLAP 數(shù)據(jù),和普通 TiKV 節(jié)點(diǎn)不一樣的是,在 TiFlash 內(nèi)部,數(shù)據(jù)是以 列存儲(chǔ)格式,主要的功能是為分析型的場(chǎng)景加速。

上圖為 TiDB HTAP 形態(tài)架構(gòu),其中包含 TiFlash 節(jié)點(diǎn)。TiFlash 提供列式存儲(chǔ),且擁有借助 ClickHouse 高效實(shí)現(xiàn)的協(xié)處理器層。

TiFlash 以 低消耗不阻塞 TiKV 寫入的方式,實(shí)時(shí)復(fù)制 TiKV 集群中的數(shù)據(jù),并同時(shí)提供與 TiKV 一樣的 一致性讀取,且可以保證讀取到最新的數(shù)據(jù)。TiFlash 中的 Region 副本與 TiKV 中完全對(duì)應(yīng),且會(huì)跟隨 TiKV 中的 Leader 副本同時(shí)進(jìn)行分裂與合并。

TiFlash 可以兼容 TiDB 與 TiSpark 兩種計(jì)算引擎,TiDB 適合用于中等規(guī)模的 OLAP 計(jì)算,而 TiSpark 適合大規(guī)模的 OLAP 計(jì)算。

TiDB計(jì)算引擎

SQL層架構(gòu)

用戶的 SQL 請(qǐng)求會(huì)直接或者通過 Load Balancer 發(fā)送到 TiDB Server,TiDB Server 會(huì)解析 MySQL Protocol Packet,獲取請(qǐng)求內(nèi)容,對(duì) SQL 進(jìn)行語法解析和語義分析,制定和優(yōu)化查詢計(jì)劃,執(zhí)行查詢計(jì)劃并獲取和處理數(shù)據(jù)。整個(gè)流程如下圖所示:

  1. 用戶發(fā)起請(qǐng)求: 數(shù)據(jù)庫客戶端向指定的 TiDB 集群發(fā)起請(qǐng)求。
  2. 目標(biāo)數(shù)據(jù)庫響應(yīng): TiDB 集群指定 TiDB 節(jié)點(diǎn)響應(yīng)用戶的請(qǐng)求。
  3. 兩者建立會(huì)話: TiDB 集群其中一個(gè) TiDB Server 節(jié)點(diǎn)與客戶端建立會(huì)話。
  4. 對(duì)象請(qǐng)求解析: TiDB Server 節(jié)點(diǎn)對(duì)接收到的請(qǐng)求進(jìn)行語法檢查、詞法分析、對(duì)象解析,并將其轉(zhuǎn)換為關(guān)系代數(shù)結(jié)構(gòu),然后完成執(zhí)行計(jì)劃優(yōu)化。
  5. 調(diào)度并且執(zhí)行:  TiDB Server 根據(jù) PD 尋找最合適的 TiKV 副本,根據(jù)優(yōu)先級(jí)執(zhí)行 SQL,按照內(nèi)存、緩存、數(shù)據(jù)快照、磁盤存儲(chǔ)的順序查詢。
  6. 監(jiān)測(cè)任務(wù)狀態(tài): TiDB Server 監(jiān)測(cè)執(zhí)行中任務(wù)的狀態(tài)。
  7. 返回?cái)?shù)據(jù)結(jié)果: TiDB Server 將執(zhí)行結(jié)果返回給數(shù)據(jù)庫客戶端。

表數(shù)據(jù)映射到KV

由于 TiDB 底層基于鍵值對(duì)存儲(chǔ)數(shù)據(jù),TiDB 表中的 行數(shù)據(jù) 需要按照一定格式映射轉(zhuǎn)換為 鍵值對(duì):

  • 為了保證同一張表的數(shù)據(jù)放在一起,方便查找,TiDB 會(huì)為每個(gè)表分配一個(gè) 表 ID,用 TableID 表示。表 ID 是一個(gè)整數(shù),在整個(gè) 集群內(nèi)唯一。
  • TiDB 會(huì)為表中每行數(shù)據(jù)分配一個(gè) 行 ID,用 RowID 表示。行 ID 也是一個(gè)整數(shù),在表內(nèi)唯一。對(duì)于行 ID,TiDB 做了一個(gè)小優(yōu)化,如果某個(gè)表有整數(shù)型的主鍵,TiDB 會(huì)使用主鍵的值當(dāng)做這一行數(shù)據(jù)的行 ID。

每行數(shù)據(jù)按照如下規(guī)則編碼成 (Key, Value) 鍵值對(duì):

Key: tablePrefix{TableID}_recordPrefixSep{RowID}
Value: [col1, col2, col3, col4]

表索引映射到KV

TiDB 同時(shí)支持 主鍵索引 和 二級(jí)索引。與表數(shù)據(jù)映射方案類似,TiDB 為表中每個(gè)索引分配了一個(gè) 索引 ID,用 IndexID 表示。

  • 對(duì)于 主鍵索引 和 唯一索引,需要根據(jù)鍵值快速定位到對(duì)應(yīng)的 RowID,因此,按照如下規(guī)則編碼成 (Key, Value) 鍵值對(duì):

Key: tablePrefix{TableID}_indexPrefixSep{IndexID}_indexedColumnsValue
Value: RowID

  • 對(duì)于非唯一性約束的 普通二級(jí)索引,一個(gè)鍵值可能 對(duì)應(yīng)多行,需要根據(jù) 鍵值范圍 查詢對(duì)應(yīng)的 RowID。因此,按照如下規(guī)則編碼成 (Key, Value) 鍵值對(duì):

Key: tablePrefix{TableID}_indexPrefixSep{IndexID}indexedColumnsValue{RowID}
Value: null

KV映射示例

數(shù)據(jù)與 KV 的映射關(guān)系,定義如下:

tablePrefix     = []byte{'t'}
recordPrefixSep = []byte{'r'}
indexPrefixSep  = []byte{'i'}

假設(shè)表結(jié)構(gòu)如下:

CREATE_TABLE User (
    ID int,
    Name varchar(20),
    Role varchar(20),
    Age int,
    UID int,
    PRIMARY KEY (ID),
    KEY idxAge (Age),
    UNIQUE KEY idxUID (UID)
);

假設(shè)表數(shù)據(jù)如下:

1, "TiDB", "SQL Layer", 10, 10001
2, "TiKV", "KV Engine", 20, 10002
3, "PD", "Manager", 30, 10003
  • 表數(shù)據(jù)映射到KV如下:
t10_r1 --> ["TiDB", "SQL Layer", 10, 10001]
t10_r2 --> ["TiKV", "KV Engine", 20, 10002]
t10_r3 --> ["PD",   "Manager",   30, 10003]
  • 唯一索引映射到KV如下:
t10_i1_10001 --> 1
t10_i2_10002 --> 2
t10_i3_10003 --> 3
  • 非唯一索引映射到KV如下:
# 假設(shè) IndexID 為 1
t10_i1_10_1 --> null
t10_i1_20_2 --> null
t10_i1_30_3 --> null

TiKV存儲(chǔ)引擎

TiKV Region

TiKV 可以看做是一個(gè) 巨大的、有序的 KV Map,為了實(shí)現(xiàn)存儲(chǔ)的水平擴(kuò)展,數(shù)據(jù)將被分散在多臺(tái)機(jī)器上。對(duì)于一個(gè) KV 系統(tǒng),為了將數(shù)據(jù) 均衡分散 在多臺(tái)機(jī)器上,通常有兩種方案:

  • 一致性哈希(Hash): 按照 Key 做 Hash,根據(jù) Hash 值選擇對(duì)應(yīng)的存儲(chǔ)節(jié)點(diǎn)

利用哈希函數(shù)將數(shù)據(jù)節(jié)點(diǎn)均勻打散到一個(gè) 0 ~ 2^32 - 1 的順時(shí)針哈希環(huán)上面,對(duì)于數(shù)據(jù)的新增、查詢和刪除等操作者,首先通過同一個(gè)哈希函數(shù)計(jì)算數(shù)據(jù)的哈希值,然后再哈希環(huán)上順時(shí)針尋址,找到第一個(gè)數(shù)據(jù)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)訪問。如圖所示:

  • 連續(xù)分段哈希(Range): 按照 Key 分 Range,某一段連續(xù)的 Key 都保存在一個(gè)存儲(chǔ)節(jié)點(diǎn)上

TiKV 選擇了 連續(xù)分段哈希(Range) ,將整個(gè) Key-Value 空間分成很多段,每一段是一系列連續(xù)的 Key,將每一段叫做一個(gè) Region,可以用 [StartKey,EndKey) 這樣一個(gè) 左閉右開 區(qū)間來描述。每個(gè) Region 中保存的數(shù)據(jù)量默認(rèn)在 96 MiB 左右(可以通過配置修改)。

TiKV集群架構(gòu)

TiKV 參考 Google Spanner 論文設(shè)計(jì)了 multi-raft-group 的副本機(jī)制。它將數(shù)據(jù) 按照 key 的范圍 劃分成大致相等的分片 Region,每一個(gè) Region 會(huì)有多個(gè)副本(默認(rèn)是 3 個(gè)),其中一個(gè)副本是 Leader,提供讀寫服務(wù)。

TiKV 通過 PD 對(duì)這些 Region 以及副本進(jìn)行調(diào)度,以保證 數(shù)據(jù)負(fù)載 和 讀寫負(fù)載 都 均勻分散 在各個(gè) TiKV 節(jié)點(diǎn)上,保證了整個(gè)集群資源的充分利用,并且可以隨著 機(jī)器數(shù)量 的增加 水平擴(kuò)展。

上圖示意了一個(gè)典型的 TiKV 集群,中間有 4 個(gè)對(duì)等的 TiKV 節(jié)點(diǎn),負(fù)責(zé)存放數(shù)據(jù)。其中一個(gè) Region 存在3個(gè)副本,每個(gè)副本分布在不同的 TiKV 節(jié)點(diǎn)上。

右邊是PD 集群,負(fù)責(zé)提供集群的元數(shù)據(jù)服務(wù),比如 TiKV 節(jié)點(diǎn)信息和數(shù)據(jù)的路由信息,即數(shù)據(jù)存放在哪個(gè) TiKV 節(jié)點(diǎn)上。

TiKV數(shù)據(jù)架構(gòu)

按 Range 分片存在的問題是,數(shù)據(jù)的寫入、讀取可能集中在某一個(gè) Region 上,造成計(jì)算資源、存儲(chǔ)空間的傾斜。因此,當(dāng)一個(gè) Region 的數(shù)據(jù)量 超過閾值 時(shí),TiKV 自動(dòng)將其 分裂 成多個(gè)更小的 Region;當(dāng)一個(gè) Region 的數(shù)據(jù)量 低于閾值 時(shí),TiKV 自動(dòng)將其與相鄰的 Region 合并。

TiKV 采用了 分層架構(gòu)設(shè)計(jì),將功能劃分為四個(gè)層級(jí),每一層都只負(fù)責(zé)自己的事情。

  • TiKV API 負(fù)責(zé) gRPC KV API 邏輯,Coprocessor API 負(fù)責(zé) TiDB 的算子下推計(jì)算
  • Transaction 負(fù)責(zé)數(shù)據(jù)的讀寫沖突和事務(wù)的隔離性
  • Raft 負(fù)責(zé)節(jié)點(diǎn)間數(shù)據(jù)同步,保證數(shù)據(jù)的安全性
  • RocksDB 負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)

網(wǎng)絡(luò)層

首先是網(wǎng)絡(luò)層,TiKV 使用了高性能的 gRPC 作為網(wǎng)絡(luò)通信框架。TiKV 對(duì)外暴露了多種形式的接口,包括支持事務(wù)的 KV 服務(wù)、高性能但不支持事務(wù)的純 KV 服務(wù),還有用于加速 SQL 查詢的計(jì)算下推服務(wù)。

事務(wù)層

在網(wǎng)絡(luò)層之下,是事務(wù)層。TiKV 實(shí)現(xiàn)了一個(gè)基于 Percolator 算法的事務(wù)處理機(jī)制,支持 樂觀事務(wù)。此外,TiKV 還對(duì) Percolator 做了改進(jìn),加入了對(duì) 悲觀事務(wù) 的支持。

用戶可以根據(jù)業(yè)務(wù)負(fù)載特點(diǎn),靈活選擇 事務(wù)模式:

  • 如果業(yè)務(wù)依賴于 MySQL 事務(wù) 的行為,可以選擇悲觀事務(wù)模式
  • 如果業(yè)務(wù)沖突較少,則可以選擇樂觀事務(wù),以獲得更高的吞吐量和較低的延遲

事務(wù)層提供了快照隔離的特性和事務(wù) ACID 屬性中的 ACI(原子性、一致性、隔離性)特性,而 D(持久性)特性由下一層實(shí)現(xiàn)。

一致性層

接下來是一致性層,該層提供了最基本的 鍵值操作接口,如 kv put/kv delete/kv get/snapshot。在一致性層內(nèi)部,TiKV 實(shí)現(xiàn)了 Raft 一致性算法,保證 強(qiáng)一致性。

TiKV 還擴(kuò)展了 Raft 算法,并引入了 multi-raft 算法,使數(shù)據(jù)能夠自動(dòng)分片。通過 multi-raft 算法,每個(gè) Region 的大小可以保持在大約 96MB,而 PD(Placement Driver)則可以通過調(diào)度實(shí)現(xiàn)水平擴(kuò)展。

存儲(chǔ)層

最底層是 RocksDB,作為高效的鍵值存儲(chǔ)引擎,它是 TiKV 真正存儲(chǔ)數(shù)據(jù)的地方。RocksDB 提供了 持久化存儲(chǔ)的能力,并被 TiKV 內(nèi)部的各個(gè)層級(jí)用來讀寫數(shù)據(jù)。

每個(gè) TiKV 實(shí)例中有 兩個(gè) RocksDB 實(shí)例,一個(gè)用于存儲(chǔ) Raft 日志(通常被稱為 raftdb),另一個(gè)用于存儲(chǔ) 用戶數(shù)據(jù) 以及 MVCC 信息(通常被稱為 kvdb)。kvdb 中有四個(gè) ColumnFamily:raft、lock、default 和 write:

  • raft 列: 存儲(chǔ)各個(gè) Region 的 元信息,僅占極少量空間。
  • lock 列: 存儲(chǔ)悲觀事務(wù)的 悲觀鎖,以及分布式事務(wù)的 一階段 Prewrite 鎖。當(dāng)分布式事務(wù)提交之后,lock cf 中的數(shù)據(jù)會(huì)被快速刪除。因此,大部分情況下 lock cf 中的數(shù)據(jù)也很少(少于 1GB)。
  • write 列: 存儲(chǔ) 表數(shù)據(jù) 以及 MVCC 信息(該數(shù)據(jù)所屬事務(wù)的開始時(shí)間以及提交時(shí)間)。當(dāng)用戶寫入了一行數(shù)據(jù)時(shí),如果該行數(shù)據(jù)長(zhǎng)度小于 255 字節(jié),那么會(huì)被存儲(chǔ) write 列中,否則該行數(shù)據(jù)會(huì)被存入到 default 列中。
  • default 列: 用于存儲(chǔ)超過 255 字節(jié)長(zhǎng)度的數(shù)據(jù)。

把 TiKV 集群架構(gòu) 和 數(shù)據(jù)架構(gòu) 整合起來,TiKV 集群的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)大致如圖所示:

RocksDB原理

TiKV 使用 RocksDB 作為底層存儲(chǔ)引擎,RocksDB 是一種 內(nèi)嵌式 的 KV 存儲(chǔ)引擎,因此可以將 RocksDB 理解為一個(gè) 單機(jī)持久化 Key-Value Map。

由于 RocksDB 是 TiKV 底層存儲(chǔ)的核心引擎,所以接下來會(huì)花大篇幅介紹 RocksDB 的 內(nèi)部構(gòu)造 和部分 優(yōu)化原理。

RocksDB 是由 Facebook 基于 Google LevelDB 開發(fā)的一款提供鍵值存儲(chǔ)和讀寫功能的 LSM-tree 架構(gòu)引擎。

可見,RocksDB 底層基于 LSM-tree 實(shí)現(xiàn)。LSM Tree(Log Structured Merge Tree,日志結(jié)構(gòu)合并樹) 是一種數(shù)據(jù)存儲(chǔ)模型,而不是某一種具體的樹型的數(shù)據(jù)結(jié)構(gòu)。

LSM 樹的核心思想是順序 IO 遠(yuǎn)快于隨機(jī) IO,因此適用于寫多讀少的業(yè)務(wù)場(chǎng)景。

LSM Tree結(jié)構(gòu)

LSM樹是一種用于 鍵值存儲(chǔ) 的 數(shù)據(jù)結(jié)構(gòu)。LSM 的基本思想是將所有的數(shù)據(jù)修改操作(如插入、更新、刪除)都記錄在一個(gè) 順序日志文件 中,這個(gè)日志文件又稱為 預(yù)寫日志(Write-Ahead Log,WAL) 。順序日志文件的好處是 順序?qū)懭耄啾?nbsp;隨機(jī)寫入 的 性能更好。

除了TiKV以外,Hbase、Cassandra和MongoDB等NoSQL底層的存儲(chǔ)模型用的是LSM。

WAL(預(yù)寫日志)

為了防止 內(nèi)存斷電 而丟失,LSM 在寫入 Memtable 之前,會(huì)先將 增刪查改操作 備份到 WAL 磁盤日志,在系統(tǒng)故障時(shí),WAL 可以用來恢復(fù)丟失的數(shù)據(jù)。

WAL 是一個(gè)只允許追加的文件,包含一組更改記錄序列。每個(gè)記錄包含鍵值對(duì)、記錄類型(Put / Merge / Delete)和校驗(yàn)和(checksum)。

Memtable(內(nèi)存表)

Memtable 是 內(nèi)存數(shù)據(jù)結(jié)構(gòu),可以使用 跳躍表 或 紅黑樹 來實(shí)現(xiàn),以保持?jǐn)?shù)據(jù)的 有序性。當(dāng) Memtable 達(dá)到一定的數(shù)據(jù)量后,Memtable 會(huì)轉(zhuǎn)化成為 ****Immutable Memtable,同時(shí)會(huì)創(chuàng)建一個(gè)新的 Memtable 來存儲(chǔ)新數(shù)據(jù)。

跳表:跳表是一種非常簡(jiǎn)單的鏈狀二分搜索結(jié)構(gòu),期望時(shí)間復(fù)雜度 O(log n) ,最壞 O(n)

Immutable Memtable(不可變內(nèi)存表)

Memtable 存儲(chǔ)的數(shù)據(jù)達(dá)到一定數(shù)量后,就會(huì)把它拷貝一份出來成為 Immutable Memtable。

Immutable Memtable 在內(nèi)存中是 不可修改 的數(shù)據(jù)結(jié)構(gòu),它是處于 Memtable 和 SSTable 之間的一種 中間狀態(tài),目的是避免在轉(zhuǎn)存過程中 不阻塞寫操作。寫操作可以由新的 Memtable 處理,避免由于 Memtable 直接寫入磁盤造成的 IO 阻塞。

SSTable

內(nèi)存中的 Immutable Memtable 是有大小限制的,需要 定期持久化 到磁盤上的 SSTable。

SSTable 是 Sorted String Table 的簡(jiǎn)稱,是一種 高性能 的 有序鍵值對(duì) 存儲(chǔ)結(jié)構(gòu),由于鍵是有序的,查找鍵可以采用 二分搜索。

為了優(yōu)化讀取性能,LSM 樹使用了 多層級(jí) 的 SSTable 文件。具體來說,RocksDB 的 SSTable 從 Level 0 到 Level N 分為多層,每層包含多個(gè) SSTable 文件。層級(jí)越高的 SSTable 數(shù)據(jù)越新,層級(jí)越低的 SSTable 數(shù)據(jù)越舊。

SSTable 的基本組成部分包括:

  • 數(shù)據(jù): 這是存儲(chǔ)在 SSTable 中的實(shí)際數(shù)據(jù)。數(shù)據(jù)被組織成鍵值對(duì),并且每個(gè)鍵值對(duì)都被寫入到磁盤中。
  • 索引: 除了數(shù)據(jù),SSTable 還包含一個(gè)索引,這個(gè)索引用于快速查找數(shù)據(jù)。索引包含了所有鍵的列表,以及每個(gè)鍵在數(shù)據(jù)中的位置。
  • 元數(shù)據(jù): SSTable還包含一些元數(shù)據(jù),如創(chuàng)建時(shí)間、最后修改時(shí)間等。

SSTable 的優(yōu)點(diǎn)包括:

  • 數(shù)據(jù)的有序性: SSTable 中的數(shù)據(jù)是有序的,這使得查找數(shù)據(jù)變得非常快速。
  • 數(shù)據(jù)的持久性: SSTable 中的數(shù)據(jù)被寫入到磁盤中,因此即使在系統(tǒng)重啟后,數(shù)據(jù)也不會(huì)丟失。
  • 數(shù)據(jù)的壓縮: SSTable 中的數(shù)據(jù)被壓縮,這使得存儲(chǔ)的數(shù)據(jù)量更小,提高了存儲(chǔ)效率。
  • 數(shù)據(jù)的恢復(fù): SSTable 中的數(shù)據(jù)可以被恢復(fù),這使得數(shù)據(jù)庫的備份和恢復(fù)變得非常簡(jiǎn)單。

RocksDB寫操作

RocksDB 中寫入操作的原理見下圖:

  1. 寫入時(shí)首先寫 WAL 日志文件,方便 進(jìn)程閃崩 時(shí)可以根據(jù)日志快速恢復(fù)。
  2. 將請(qǐng)求寫入到內(nèi)存中的跳表 SkipList 即 Memtable 中,立即 返回給客戶端。當(dāng) Memtable 寫滿后,將其轉(zhuǎn)換成 Immutable Memtable,并切換到新的 Memtable 提供寫入。
  3. RocksDB 在后臺(tái)會(huì)通過一個(gè) flush 進(jìn)程 將這個(gè) Memtable 刷新到磁盤,生成一個(gè) Sorted String Table(SST) 文件,放在 Level 0 層,刪除 對(duì)應(yīng)的 WAL 日志。L0 層 的文件,是由內(nèi)存中的 Memtable dump 到磁盤上生成的,單個(gè) 文件內(nèi)部 按 key 有序,文件之間無序,而 L1 ~ L6 層 的文件都是按照 key 有序;
  4. 當(dāng) Level 0 層 的 SST 文件個(gè)數(shù)超過 閾值 之后,就會(huì)通過 Compaction 策略 將其放到 Level 1 層,以此類推。每一層的數(shù)據(jù)是上一層的 10 倍(因此 90% 的數(shù)據(jù)存儲(chǔ)在最后一層)。

RocksDB讀操作

RocksDB 中讀取操作的原理見下圖:

  1. 首先在 Memtable 中查找指定的 key,如果查到符合條件的數(shù)據(jù),結(jié)束查找。
  2. 然后在 Immutable Memtable 中查找指定的 key,如果查到符合條件的數(shù)據(jù),結(jié)束查找。
  3. 按 低層 至 高層 的順序,從 level 0 層到 level 1 層的 SST文件 中查找指定的 key,如果查到符合條件的數(shù)據(jù),結(jié)束查找,否則返回 Not Found 錯(cuò)誤。

Compaction操作

RocksDB 通過 追加寫 的方式記錄 數(shù)據(jù)修改操作:

  • Insert 操作: 直接寫入新的 KV
  • Update 操作: 寫入修改后的 KV
  • Delete 操作: 寫入一條 tombstone 標(biāo)記刪除 的記錄

通過這種方式,將磁盤的 隨機(jī)寫入 轉(zhuǎn)換為 順序?qū)懭耄岣吡藢懭胄阅埽矌砹艘韵聠栴}:

  1. 大量的冗余和無效數(shù)據(jù) 占用磁盤空間,造成 空間放大。
  2. 如果在內(nèi)存中沒有讀取到數(shù)據(jù),需要從 L0 層開始查找 SST 文件,造成 讀放大。

因此,RocksDB 引入了 compaction 操作,依次將 L(N) 層 的數(shù)據(jù)合并到下一層 L(N+1) 層,同時(shí)清理標(biāo)記刪除的數(shù)據(jù),從而降低 空間放大、讀放大 的影響。

Compaction的機(jī)制

RocksDB 在邏輯上把 SSTable 文件劃分成 多個(gè)層級(jí)(7 層),并且滿足以下性質(zhì):

  1. 層級(jí)越高 說明其數(shù)據(jù)寫入越早,即先往 上層進(jìn)行 “放”(minor compaction) ,上層 “滿”(達(dá)到容量限制) 之后 “溢”(major compaction)到下層 進(jìn)行 合并。
  2. 每層文件 總大小 都有限制,層級(jí)大小 成指數(shù)級(jí)增長(zhǎng)。比如 L0 層 文件總大小上限為 10MB,L1 層 為  100MB,L21 層 為 1000MB。依次類推,最下層(L6 層)沒有限制。
  3. 由于 L0 層 每個(gè) SSTable 文件 都是直接由 Memtable 落盤而來,因此 L0 層 多個(gè) SSTable 文件的 key 范圍可能會(huì)有 重合。而其他層(L1 ~ L6)的多個(gè) SSTable 文件,則通過一些規(guī)則保證 沒有重合。

Compaction的作用

  1. 數(shù)據(jù)持久化: 將內(nèi)存中的數(shù)據(jù)持久化到磁盤中的 SSTable 文件
  2. 提高讀寫效率: 將 L0 層的 SSTable 文件合并為若干個(gè) 沒有數(shù)據(jù)重合 的 L1 ~L6 層文件,避免多層無效遍歷
  3. 平衡讀寫差異: 當(dāng) L0 層SSTable 文件數(shù)量過多時(shí),暫停 寫入操作,直到 compaction 完成為止
  4. 節(jié)約磁盤空間: 同一個(gè) key 可能存在著多條數(shù)據(jù),對(duì)不同版本進(jìn)行 合并 可以節(jié)省磁盤空間。

Compaction的類型

RocksDB 的 Compaction 操作分為兩類,分別是 Minor Compaction 和 Major Compaction。

  • Minor Compaction

Minor Compaction 是指將 Immutable MemTable 轉(zhuǎn)存為 SSTable 文件寫入 L0 層

  • Major Compaction

Major Compaction 是指 合并壓縮 第 L(N) 層 的多個(gè) SSTable 文件到第 L(N+1) 層

Major Compaction 的觸發(fā)條件:

當(dāng) L0 層 SSTable 文件數(shù) 超過預(yù)定的上限(默認(rèn)為4個(gè))

當(dāng) L(N) 層文件的 總大小 超過(10 ^ i) MB

當(dāng)某個(gè) SSTable 文件 無效讀取 的次數(shù)過多

布隆過濾器(Bloom Filter)

為了減小 讀放大 導(dǎo)致性能下降,RocksDB 采取了以下兩種策略:

  • 通過 major compaction 盡量減少 SSTable 文件數(shù)
  • 使用 布隆過濾器,快速判斷 key 是否在某個(gè) SSTable 文件中

布隆過濾器底層使用一個(gè) 位數(shù)組(bit array) ,初始集合為空時(shí),所有位都為 0:

當(dāng)往集合中插入一個(gè) 數(shù)據(jù) x 時(shí),利用 k 個(gè) 獨(dú)立的 哈希函數(shù) 分別對(duì) x 進(jìn)行散列,然后將 k 個(gè)散列值 按數(shù)組長(zhǎng)度取余后,分別將位數(shù)組位置置為 1:

查找過程和插入過程類似,也是利用同樣的 k 個(gè)哈希函數(shù) 對(duì)待 查找數(shù)據(jù) 按順序進(jìn)行哈希,得到 k 個(gè)位置。

  • 如果位數(shù)組中 k 個(gè)位置上的 位均為 1,則該元素 有可能 存在
  • 如果任意一位置上值為 位為0,則該值 一定不存在。

布隆過濾器用于快速判斷一條數(shù)據(jù)是否在集合中。其本質(zhì)上是通過容忍一定的錯(cuò)誤率,來換取時(shí)空的高效性。

RocksDB 并未使用 k 個(gè)哈希函數(shù),而是用了 double-hashing 方法,利用一個(gè)哈希函數(shù)達(dá)到近似 k 個(gè)哈希函數(shù)的效果。

結(jié)語

本文詳細(xì)介紹了 TiDB 的核心組件,尤其是用于 OLTP 的分布式 計(jì)算引擎 TiDB 和分布式 存儲(chǔ)引擎 TiKV。一方面闡述了 TiDB 是如何將 關(guān)系型表數(shù)據(jù) 、索引數(shù)據(jù) 轉(zhuǎn)換為 鍵值對(duì) 數(shù)據(jù);另一方面,深度剖析了 TiKV 內(nèi)部的架構(gòu)設(shè)計(jì)和原理,尾篇大幅介紹了 TiKV 底層引入的 單機(jī)鍵值對(duì) 數(shù)據(jù)庫 RocksDB 的原理,一定程度讓大家知其然也知其所以然。本文拋磚引玉,關(guān)于 TiDB 內(nèi)部的分布式通信、一致性原理、MVCC、GC清理算法、一些巧妙數(shù)據(jù)結(jié)構(gòu),仍需大家深入研究方可融會(huì)貫通,活學(xué)活用。

作者介紹

陳林,51CTO社區(qū)編輯,某零售銀行龍頭DevOps持續(xù)集成平臺(tái)技術(shù)負(fù)責(zé)人,主導(dǎo)核心業(yè)務(wù)方案設(shè)計(jì)落地,推動(dòng)產(chǎn)品架構(gòu)持續(xù)演進(jìn)。

責(zé)任編輯:華軒 來源: 51CTO
相關(guān)推薦

2021-08-26 05:02:50

分布式設(shè)計(jì)

2019-11-19 09:00:00

數(shù)據(jù)庫架構(gòu)設(shè)計(jì)

2022-01-12 08:54:52

Spring編程架構(gòu)設(shè)計(jì)

2022-09-28 09:12:16

HBase分布式數(shù)據(jù)庫數(shù)據(jù)庫

2022-01-13 09:38:25

Android架構(gòu)設(shè)計(jì)

2022-03-06 23:14:56

緩存分布式系統(tǒng)

2024-03-07 18:11:39

Golang采集鏈接

2024-03-25 14:31:45

2023-09-21 10:47:29

分布式CAPBASE

2021-10-18 11:58:56

負(fù)載均衡虛擬機(jī)

2023-08-27 16:11:35

數(shù)據(jù)庫分布式事務(wù)數(shù)據(jù)庫

2025-08-13 07:31:29

2022-09-06 08:02:40

死鎖順序鎖輪詢鎖

2023-12-26 01:00:49

分布式事務(wù)TCC

2020-01-03 09:00:00

數(shù)據(jù)庫數(shù)據(jù)庫管理金融

2021-02-19 10:42:58

Redisson分布式鎖源碼解析

2023-03-07 09:49:04

分布式數(shù)據(jù)庫

2021-01-19 05:49:44

DNS協(xié)議

2022-03-28 10:56:11

Python字符串格式化

2022-09-14 09:01:55

shell可視化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

你懂得在线网址| 欧美精品videos极品| 88xx成人永久免费观看| 国产精品久久看| 99高清视频有精品视频| 日本午夜视频在线观看| 青青草91久久久久久久久| 欧美一级片在线看| 国产特级黄色大片| 麻豆tv在线| 91免费小视频| 亚洲aⅴ日韩av电影在线观看| 国产污视频在线看| 日韩久久久久| 日韩精品一二三四区| 污污的网站免费| 一个人www视频在线免费观看| 亚洲天堂福利av| 欧美日韩一区在线视频| 国产哺乳奶水91在线播放| 久久亚洲欧洲| 韩国19禁主播vip福利视频| 日本一级免费视频| jizz性欧美23| 在线不卡欧美精品一区二区三区| 播放灌醉水嫩大学生国内精品| 超碰超碰在线| 国产欧美日韩不卡免费| 久久99精品国产99久久| 99精品人妻无码专区在线视频区| 蘑菇福利视频一区播放| 欧美激情一区二区久久久| www久久久久久久| 视频小说一区二区| 欧美变态tickle挠乳网站| www.夜夜爽| 欧美va在线观看| 精品欧美aⅴ在线网站| 国产尤物av一区二区三区| 午夜在线小视频| 国产日本欧美一区二区| 欧美日韩在线观看一区二区三区| 欧性猛交ⅹxxx乱大交| 国产毛片精品一区| 国产精品高潮呻吟视频| 亚洲高清毛片一区二区| 99热精品在线观看| 久久久久久久久久久国产| 丁香花五月激情| 91精品一区二区三区综合在线爱| 日韩一区二区精品视频| 日韩一卡二卡在线观看| 青青草国产免费一区二区下载| 亚洲人成在线观看| 久久久久久九九九九九| 亚洲图片久久| 亚洲欧美在线免费观看| 亚洲天堂久久新| 亚洲自拍都市欧美小说| 亚洲欧洲第一视频| 国产又粗又猛又爽视频| 禁果av一区二区三区| 亚洲欧美日韩视频一区| 中文字幕第24页| 欧美综合另类| xxxx欧美18另类的高清| 免费中文字幕在线| 黄色免费成人| 456亚洲影院| 亚洲黄网在线观看| 麻豆91在线播放免费| 91在线国产电影| 亚洲精品字幕在线观看| 成人教育av在线| 蜜桃视频在线观看成人| 国产黄在线播放| 国产精品传媒入口麻豆| 男女裸体影院高潮| 蜜桃视频在线观看播放| 色视频欧美一区二区三区| 在线观看的毛片| 精品一区91| 日韩精品一二三四区| 美女100%露胸无遮挡| 一区二区不卡| 国语自产精品视频在线看抢先版图片| 手机看片久久久| 激情小说亚洲一区| 高清视频一区| 成人在线免费视频| 樱花草国产18久久久久| 欧美成人一区二区在线观看| 国产欧美在线观看免费| 欧美成人a∨高清免费观看| 久久国产精品无码一级毛片| 日韩国产在线| 国内精品在线一区| 中文字幕乱码在线观看| 成人中文字幕合集| 日韩和欧美的一区二区| 色婷婷在线播放| 欧美中文字幕久久| 色哟哟视频在线| 欧美成人精品一区二区三区在线看| 久久久女人电视剧免费播放下载 | 日韩一区二区在线| 九九热这里只有精品6| 日韩精品成人免费观看视频| 国产一区在线精品| 欧美在线视频一区二区三区| 日本欧美电影在线观看| 欧美视频在线一区二区三区| 欧美一级片黄色| 天天综合网91| 国产精品扒开腿做爽爽爽男男| 国产小视频一区| 亚洲视频在线一区二区| 六月激情综合网| 9l亚洲国产成人精品一区二三| 有码中文亚洲精品| 99久热在线精品996热是什么| 国产一级精品在线| 手机成人在线| 日本韩国欧美| 日韩大片免费观看视频播放| 妺妺窝人体色www聚色窝仙踪| 日本成人在线电影网| 久久精品日产第一区二区三区 | 成人免费一级视频| 亚洲四区在线观看| av无码精品一区二区三区| 91成人午夜| 欧美裸体男粗大视频在线观看| 亚洲av无码乱码国产精品fc2| 99re8在线精品视频免费播放| 国产成人一区二区三区别| 电影中文字幕一区二区| 在线观看国产精品91| 无码人妻av免费一区二区三区| 不卡在线观看av| 久久久久99精品成人片| 91精品入口| 欧美—级高清免费播放| 国产黄色大片网站| 亚洲六月丁香色婷婷综合久久| 国内国产精品天干天干| 91日韩免费| 成人国产精品色哟哟| 在线观看麻豆| 欧美日韩国产高清一区二区三区| 久久久精品成人| 蜜臀av在线播放一区二区三区 | 色哟哟免费在线观看| 欧美中文字幕亚洲一区二区va在线| 中文字幕免费高清| 日日夜夜精品视频天天综合网| 日韩av在线一区二区三区| jizzjizz少妇亚洲水多| www.亚洲男人天堂| 国产精品老熟女视频一区二区| 亚洲视频小说图片| 日韩大尺度视频| 99在线|亚洲一区二区| 麻豆av一区二区| se01亚洲视频| 精品久久久91| 成 人 黄 色 片 在线播放| 亚洲国产日韩a在线播放| fc2成人免费视频| 西西人体一区二区| 亚洲韩国在线| 日韩精品免费视频一区二区三区 | 欧美不卡高清一区二区三区| 亚洲欧洲一区二区三区久久| 日本黄色一级视频| 国产精品情趣视频| 中文字幕久久久久久久| 亚洲区第一页| 亚洲v日韩v欧美v综合| av日韩一区| 97久久精品人搡人人玩| 国产对白叫床清晰在线播放| 欧美高清视频不卡网| 久久精品视频久久| 99国产精品99久久久久久| 日韩欧美xxxx| 影音先锋成人在线电影| 精品久久久久久中文字幕动漫| 欧美色片在线观看| 九九热这里只有在线精品视| 日本韩国精品一区二区| 欧美男人的天堂一二区| 国产成人在线免费观看视频| 中文字幕不卡一区| 国产国语老龄妇女a片| 日韩国产欧美在线播放| 欧美黄色免费网址| 欧美一级精品| 国产伦视频一区二区三区| 欧美色片在线观看| 97精品免费视频| 黄色在线论坛| 亚洲视频第一页| 性生活免费网站| 在线中文字幕一区二区| 免费一级片在线观看| 国产清纯在线一区二区www| 18深夜在线观看免费视频| 日韩av不卡一区二区| 加勒比成人在线| 国产高清一区| 任我爽在线视频精品一| 久久亚州av| 亚洲在线www| 久久久久久一区二区三区四区别墅| 97视频人免费观看| av大片在线| 日韩综合视频在线观看| 狠狠色伊人亚洲综合网站l| 欧美成人性战久久| 一区二区三区精彩视频| 在线观看日韩精品| 日本中文字幕在线| 亚洲高清免费视频| 91成人福利视频| 亚洲私人影院在线观看| 亚洲色图日韩精品| 国产欧美日韩中文久久| 久久久无码人妻精品一区| 波多野洁衣一区| 国产xxx在线观看 | 国产精品第七页| 成人精品鲁一区一区二区| 日本黄色www| 国产一区二区网址| 在线一区二区不卡| 久久99国产精品免费网站| 美女一区二区三区视频| 日韩中文字幕av电影| 国产综合免费视频| 午夜一区不卡| 久久久久久久久久久免费视频| 亚洲深夜av| 自拍日韩亚洲一区在线| 在线视频观看日韩| av7777777| 久久福利一区| 国产精品亚洲a| 日韩制服丝袜先锋影音| 久久综合久久色| 日本少妇一区二区| 亚洲一级免费观看| 麻豆国产精品官网| 国内自拍第二页| 韩国v欧美v日本v亚洲v| 午夜免费视频网站| 福利一区在线观看| 欧美xxxxx精品| 久久久夜色精品亚洲| 在线免费观看视频| 日本一区二区三区久久久久久久久不 | 日本一区二区三区视频在线看| yellow视频在线观看一区二区| 4438全国亚洲精品观看视频| 国产一区二区高清不卡 | 国产成年人在线观看| 欧美日韩a区| 91视频 -- 69xx| 首页国产欧美久久| 熟女人妇 成熟妇女系列视频| 亚洲一区激情| xx欧美撒尿嘘撒尿xx| 国产原创一区二区三区| 在线免费看黄色片| 国产目拍亚洲精品99久久精品| 亚洲一区二区三区久久| 日韩精品一区国产| 国产无套精品一区二区| 久久av免费看| 在线无限看免费粉色视频| 欧美欧美全黄| 无码人妻h动漫| 精品一区二区在线播放| 亚洲一级Av无码毛片久久精品| 99久久精品免费观看| 久久视频一区二区三区| 亚洲一区二区影院| 蜜臀精品一区二区三区| 欧美日韩成人一区二区| 欧美亚洲精品在线观看| 在线观看日韩欧美| 日韩三级免费| 国产成人亚洲综合| 午夜久久av| 日韩一区不卡| 亚洲黄网站黄| 免费成年人高清视频| av毛片久久久久**hd| 国产三级黄色片| 亚洲va国产va欧美va观看| 一区二区视频网站| 亚洲国产精品成人va在线观看| 日韩美女网站| 日本aⅴ大伊香蕉精品视频| 久久久久久久久久久久电影| 女女同性女同一区二区三区91| 亚洲欧美一级二级三级| 男人天堂成人在线| aa级大片欧美| 538精品在线观看| 精品1区2区3区| 秋霞av在线| 97国产真实伦对白精彩视频8| 99综合99| 一区高清视频| 日韩va欧美va亚洲va久久| 国产xxxxxxxxx| 亚洲一区二区视频在线观看| 国产一区二区在线播放视频| 亚洲天堂免费观看| 免费毛片b在线观看| 2022国产精品| 国产精品福利在线观看播放| 黄色av免费在线播放| 99精品视频一区二区| 久草视频中文在线| 欧美一区二区三区四区高清| 91福利在线视频| 国产精品草莓在线免费观看| 老汉色老汉首页av亚洲| 日韩在线观看a| 国产成人av一区二区| 91嫩草丨国产丨精品| 8x福利精品第一导航| 色开心亚洲综合| 91精品久久久久久久久青青| 日本一区二区在线看| 韩国中文字幕av| 日本一区二区三区免费乱视频| 波多野结衣av无码| 亚洲视频精品在线| 成人在线网站| 性欧美精品一区二区三区在线播放| 日欧美一区二区| 欧美一区二区三区粗大| 欧美日韩一区在线观看| 69xxxx欧美| 成人有码视频在线播放| 亚洲高清影视| 久久久久99人妻一区二区三区 | 日本一级片免费| 欧美精品国产精品| 成年人黄视频在线观看| 99re视频在线观看| 国产精品大片免费观看| 黄色性视频网站| 一本色道久久综合亚洲精品按摩| 国产黄在线观看免费观看不卡| 国产精品一区二区三区毛片淫片 | 中文字幕一区二区三区日韩精品| 国产性生活免费视频| 丁香激情综合五月| 91香蕉在线视频| 亚洲视频777| 成年永久一区二区三区免费视频| 桥本有菜av在线| 处破女av一区二区| 天天干天天干天天操| 最近免费中文字幕视频2019| 超碰国产精品一区二页| 日韩 欧美 视频| 2021国产精品久久精品| 伊人免费在线观看高清版| 欧美xxxx做受欧美.88| 国产伦乱精品| 亚洲福利精品视频| 亚洲精品久久久久久国产精华液| 天堂中文在线官网| 国产精品视频一区二区三区四| 欧美影院一区| av鲁丝一区鲁丝二区鲁丝三区| 欧美伊人久久久久久久久影院| 国产黄色在线观看| 国产综合av一区二区三区| 青青草成人在线观看| 国产性一乱一性一伧一色| 亚洲偷欧美偷国内偷| 亚洲一区电影| 99视频在线免费| 亚洲一区二区三区四区中文字幕 | 欧美电影免费网站| 中文久久久久久| 亚洲韩国精品一区| 在线视频1区2区| 国产在线一区二区三区四区 | 黑人巨大精品欧美一区免费视频 | 国外av在线| 成人三级视频在线观看一区二区| 日韩成人精品视频| 日韩av在线播|