AntDB-M高效能設計之hash索引動態rehash
A n t D B - M 支 持 h a s h 索 引 、 b t r e e 索 引 等 索 引 類 型 , h a s h 索 引 以 h a s h 表 的 方 式 實 現 , 一 個 簡 單 的 h a s h 表 示 意 圖 如 圖 1 所 示 。 h a s h 桶 下 的 元 素 節 點 為 單 向 或 者 雙 向 鏈 表 , 數 據 行 上 某 一 個 或 者 某 幾 個 字 段 組 成 索 引 , 通 過 h a s h 函 數 對 索 引 字 段 的 值 進 行 運 算 , 映 射 到 某 個 h a s h 桶 下 , h a s h 桶 下 的 元 素 節 點 存 儲 了 數 據 行 的 行 號 。
當 使 用 s e l e c t * f r o m t a b l e w h e r e a = v a l u e ; 進 行 查 詢 時 , 先 根 據 v a l u e 計 算 h a s h 值 , 算 出 在 第 幾 個 h a s h 桶 , 然 後 遍 歷 h a s h 桶 下 的 元 素 , 根 據 存 儲 的 行 號 , 取 出 每 一 行 a 列 存 儲 的 值 , 與 v a l u e 進 行 比 對 , 若 完 全 相 等 , 則 就 是 要 找 的 行 。
以 h a s h 桶 下 的 節 點 為 雙 向 鏈 表 舉 例 , 桶 下 的 元 素 節 點 結 構 一 般 為
struct node{ uint8 oid; // 資料行行號或者其它含義的value node * node_prev; // 上一個節點 node * node_next; // 下一個節點}
s i z e o f ( n o d e ) 總 共 8 + 8 + 8 = 2 4 個 字 節 ;
對 於 A n t D B - M 來 講 , 內 存 是 非 常 寶 貴 的 資 源 , 在 實 現 h a s h 索 引 且 保 證 性 能 的 前 提 下 , 內 存 佔 用 必 須 盡 量 小 。 對 於 數 據 庫 裡 的 某 張 表 , 假 設 表 總 共 有 m 行 , 表 上 有 n 個 h a s h 索 引 , 則 這 張 表 就 有 n 套 h a s h 結 構 , 每 套 h a s h 結 構 有 m 個 桶 節 點 , 以 上 述 雙 向 鏈 表 為 例 , 這 張 表 的 h a s h 索 引 佔 用 的 內 存 為 n * ( h a s h 索 引 頭 節 點 佔 用 內 存 + m * 2 4 字 節 ) , 2 4 個 字 節 有 時 甚 至 比 數 據 表 中 這 行 數 據 本 身 還 要 大 。
為 了 減 少 索 引 數 據 的 內 存 佔 用 , A n t D B - M 使 用 數 組 元 素 來 模 擬 鏈 表 節 點 , 不 再 額 外 分 配 空 間 存 儲 鏈 表 節 點 的 值 。 一 次 性 分 配 所 有 的 節 點 , 避 免 頻 繁 的 內 存 分 配 釋 放 。
struct array_node{uint8 prev_oid; // 上一個節點的位置uint8 next_oid; // 下一個節點的位置}
s i z e o f ( a r r a y _ n o d e ) 總 共 8 + 8 = 1 6 個 字 節 , o i d 為 0 代 表 上 一 個 、 下 一 個 節 點 為 空 , 即 本 節 點 的 前 面 或 者 後 面 沒 有 其 它 節 點 了 。 對 於 某 張 有 n 行 數 據 的 數 據 表 , 申 請 分 配 數 組 空 間 a r r a y _ n o d e [ n ] , 對 於 數 組 中 的 某 個 元 素 a r r a y _ n o d e [ k ] , k 有 兩 個 含 義 :
-
數 組 中 的 下 標 , 用 於 訪 問 a r r a y _ n o d e [ k ] . p r e v _ o i d 和 a r r a y _ n o d e [ k ] . n e x t _ o i d ;
-
a r r a y _ n o d e [ k ] 指 向 數 據 庫 此 表 中 的 第 k 行 , 可 以 去 訪 問 這 張 表 第 k 行 的 內 容 。 這 樣 就 避 免 存 儲 了 u i n t 8 o i d ( 數 據 行 行 號 ) , 節 省 了 1 / 3 的 內 存 空 間 ; 如 果 h a s h 桶 下 的 節 點 是 單 向 鏈 表 , 則 節 省 了 2 / 3 的 內 存 。
下 面 舉 例 說 明 :
假 設 一 張 數 據 表 初 始 建 表 時 預 分 配 了 m 行 , 則 對 應 的 h a s h 結 構 的 b u c k e t 個 數 為 n ( n 在 實 現 時 為 大 於 m 的 最 小 素 數 ) , 對 應 h a s h 索 引 的 桶 節 點 數 組 預 分 配 n 個 元 素 , 即 u i n t 8 b u c k e t _ h e a d [ n ] , b u c k e t _ h e a d 記 錄 每 個 桶 的 頭 節 點 指 向 第 幾 行 ( 也 代 表 指 向 數 組 a r r a y _ n o d e 的 第 幾 個 元 素 ) ; 分 配 連 續 數 組 a r r a y _ n o d e [ m ] , 對 應 於 b u c k e t 下 面 雙 向 鏈 接 的 節 點 元 素 。
假 設 對 於 某 個 h a s h 索 引 , 數 據 表 的 第 3 行 , 第 2 9 行 , 第 3 6 8 1 5 行 都 映 射 到 桶 2 下 , 則 桶 2 的 頭 結 點 指 向 表 上 的 第 3 行 數 據 , 也 指 向 a r r a y _ n o d e 的 第 3 個 元 素 。
bucket_head[2]=3;array_node [3] ->prev_oid=0; array_node [3] -> next_oid=29;array_node [29] ->prev_oid=3; array_node [29] ->next_oid=36815;array_node [36815] ->prev_oid=29;array_node [36815] ->next_oid=0;
這 樣 , 同 樣 做 到 了 前 後 的 遍 歷 ( n e x t _ o i d = 0 表 示 這 是 鏈 表 上 的 最 後 一 個 有 效 元 素 ) , 相 比 前 一 種 方 式 , 通 過 數 組 來 模 擬 鏈 表 , 內 存 佔 用 減 少 , 並 且 數 組 的 內 存 是 一 次 性 分 配 出 來 , 內 存 連 續 , 訪 問 速 度 快 。
隨 著 業 務 的 運 行 , 數 據 表 的 規 模 可 能 不 斷 地 擴 大 , 比 如 一 張 表 剛 創 建 時 預 分 配 1 0 0 0 萬 行 , 運 行 一 段 時 間 後 擴 展 到 5 0 0 0 萬 行 , 如 果 h a s h 結 構 的 b u c k e t 個 數 還 是 1 0 0 0 萬 左 右 , 則 每 個 b u c k e t 下 面 的 平 均 有 5 個 元 素 , h a s h 衝 突 增 大 , 查 找 效 率 降 低 。 此 時 , 我 們 需 要 對 數 據 進 行 r e h a s h , 動 態 調 整 h a s h 結 構 , 減 少 h a s h 衝 突 , 同 時 又 不 阻 塞 h a s h t a b l e 的 增 刪 改 查 。
如
圖
2
所
示
,
每
個
h
a
s
h
桶
下
面
都
有
一
把
桶
鎖
l
o
c
k
,
當
讀
取
、
插
入
、
刪
除
桶
下
元
素
時
,
需
要
對
桶
加
鎖
。
m
i
g
r
a
t
e
_
n
o
d
e
指
示
當
前
正
在
遷
移
的
b
u
c
k
e
t
,
具
體
遷
移
某
個
b
u
c
k
e
t
時
,
也
是
先
對
b
u
c
k
e
t
加
桶
鎖
,
遷
移
完
b
u
c
k
e
t
下
面
的
所
有
元
素
後
釋
放
桶
鎖
,
然
後
m
i
g
r
a
t
e
_
n
o
d
e
再
指
向
下
一
個
b
u
c
k
e
t
.
1 . 每 當 表 的 數 據 行 增 加 一 定 數 量 時 , 新 建 一 個 新 的 h a s h _ t a b l e 結 構 , 此 時 新 老 兩 套 h a s h _ t a b l e 並 存 ;
2 . 遍 歷 老 的 h a s h _ t a b l e , 從 第 一 個 桶 開 始 , 加 桶 鎖 , 遍 歷 桶 下 面 的 每 一 個 元 素 , 計 算 它 在 新 的 h a s h _ t a b l e 上 的 位 置 , 遷 移 插 入 到 新 的 h a s h _ t a b l e 結 構 ;
3 . 所 有 桶 的 元 素 遷 移 完 成 之 後 , 釋 放 老 的 h a s h _ t a b l e 結 構 , 數 據 的 增 刪 改 查 完 全 切 換 到 新 的 h a s h _ t a b l e ;
圖 2 : A n t D B - M 動 態 r e h a s h 示 意 圖
為 何 動 態 r e h a s h 的 過 程 不 阻 塞 h a s h t a b l e 的 增 刪 改 查 , 本 文 以 查 找 和 插 入 舉 例 , 用 流 程 圖 的 方 式 說 明 如 下 。 更 新 ( 分 解 為 查 找 + 刪 除 + 插 入 ) 和 刪 除 的 流 程 也 是 類 似 的 , 不 管 是 查 找 , 插 入 、 更 新 、 刪 除 , 都 要 先 在 老 的 h a s h 結 構 上 查 找 數 據 位 於 哪 個 b u c k e t 下 面 。
圖 3 : 動 態 r e h a s h 過 程 中 的 f i n d
圖 4 : 動 態 r e h a s h 過 程 中 的 i n s e r t
表 擴 容 時 動 態 擴 展 h a s h 結 構 , 不 阻 塞 A n t D B - M 服 務 及 應 用 , 對 用 戶 透 明 。 A n t D B - M 內 部 通 過 增 加 h a s h 桶 個 數 和 遷 移 桶 下 元 素 , 減 少 h a s h 衝 突 , 使 得 h a s h 索 引 性 能 不 因 數 據 行 的 增 多 而 降 低 , 快 速 定 位 數 據 。
綜 上 所 述 , h a s h 索 引 巧 妙 設 計 的 數 據 結 構 , 以 及 動 態 r e h a s h 的 並 行 算 法 使 得 A n t D B - M 的 h a s h 索 引 具 備 持 續 高 性 能 的 特 性 , 以 滿 足 復 雜 業 務 應 用 的 性 能 需 求 。
關 於 A n t D B 數 據 庫
A n t D B 數 據 庫 始 於 2 0 0 8 年 , 是 亞 信 科 技 自 主 研 發 的 分 布 式 關 系 型 數 據 庫 品 牌 , A n t D B - M 是 面 向 高 性 能 內 存 型 數 據 庫 , 是 A n t D B 的 子 產 品 之 一 , 在 運 營 商 的 核 心 系 統 上 , 為 全 國 2 4 個 省 份 的 1 0 億 多 用 戶 提 供 在 線 服 務 , 具 備 高 性 能 、 彈 性 擴 展 、 高 可 靠 等 產 品 特 性 , 峰 值 每 秒 可 處 理 百 萬 筆 通 信 核 心 交 易 , 保 障 系 統 持 續 穩 定 運 行 近 1 5 年 , 並 在 通 信 、 金 融 、 交 通 、 能 源 、 物 聯 網 等 行 業 成 功 商 用 落 地 。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026696/viewspace-2994941/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL | 05 如何設計高效能的索引?MySql索引
- 動態程式設計之classloader程式設計
- Java安全之Javassist動態程式設計Java程式設計
- 設計模式之cglib動態代理設計模式CGLib
- 23種設計模式之——動態代理模式設計模式
- Java設計模式-之代理模式(動態代理)Java設計模式
- 使用者體驗之——動態設計
- InnoDB關鍵特性之自適應hash索引索引
- JDK 高效能程式設計之容器JDK程式設計
- Java動態程式設計---動態代理Java程式設計
- 複雜報表設計之動態報表
- MySQL效能優化之索引設計MySql優化索引
- Mysql研磨之設計索引原則MySql索引
- MySQL 禁止使用 HASH 索引MySql索引
- android常用設計模式之代理設計模式及動態代理原理Android設計模式
- 《Redis 設計與實踐》讀書筆記系列五:字典 rehashRedis筆記
- RocketMQ高效能之底層儲存設計MQ
- 設計模式:動態代理設計模式
- redis字典快速對映+hash釜底抽薪+漸進式rehash | redis為什麼那麼快Redis
- 高效能儲存SIG月度動態:EROFS支援直接索引容器映象tar包等索引
- MYSQL索引及高效能索引策略MySql索引
- 設計模式_JAVA動態代理設計模式設計模式Java
- MySQL的btree索引和hash索引的區別MySql索引
- 好程式設計師分享MyBatis之動態SQL語句程式設計師MyBatisSQL
- 使用Elasticsearch的動態索引和索引優化Elasticsearch索引優化
- 設計模式之——狀態模式設計模式
- MapReduce程式設計例項之倒排索引 1程式設計索引
- Android程式設計師必會技能—執行時動態生成類—之動態代理Android程式設計師
- Android程式設計師必會技能---執行時動態生成類---之動態代理Android程式設計師
- 高效能python程式設計之協程(stackless)Python程式設計
- 動態程式設計(DynamicProgramming)程式設計
- MySQL Hash索引和B-Tree索引的區別MySql索引
- Mybatis之介面程式設計--JAVA動態代理的最佳展現MyBatis程式設計Java
- mysql索引設計MySql索引
- PHP 設計模式之狀態模式PHP設計模式
- 設計模式之狀態模式(State)設計模式
- 設計模式20之狀態模式設計模式
- Java設計模式之狀態模式Java設計模式