圖數(shù)據(jù)庫NebulaGraphTTL特性

圖數(shù)據(jù)庫 Nebula Graph TTL 特性

導(dǎo)讀

身處在現(xiàn)在這個大數(shù)據(jù)時代,我們處理的數(shù)據(jù)量需以 TB、PB, 甚至 EB 來計算,怎么處理龐大的數(shù)據(jù)集是從事數(shù)據(jù)庫領(lǐng)域人員的共同問題。解決這個問題的核心在于,數(shù)據(jù)庫中存儲的數(shù)據(jù)是否都是有效的、有用的數(shù)據(jù),因此如何提高數(shù)據(jù)中有效數(shù)據(jù)的利用率、將無效的過期數(shù)據(jù)清洗掉,便成了數(shù)據(jù)庫領(lǐng)域的一個熱點話題。在本文中我們將著重講述如何在數(shù)據(jù)庫中處理過期數(shù)據(jù)這一問題。

在天元等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供做網(wǎng)站、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作按需求定制設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計,成都全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè)公司,天元網(wǎng)站建設(shè)費用合理。

在數(shù)據(jù)庫中清洗過期數(shù)據(jù)的方式多種多樣,比如存儲過程、事件等等。在這里筆者舉個例子來簡要說明 DBA 經(jīng)常使用的存儲過程 + 事件來清理過期數(shù)據(jù)的過程。

存儲過程 + 事件清洗數(shù)據(jù)

存儲過程(procedure)

存儲過程是由一條或多條 SQL 語句組成的集合,當(dāng)對數(shù)據(jù)庫進(jìn)行一系列的讀寫操作時,存儲過程可將這些復(fù)雜的操作封裝成一個代碼塊以便重復(fù)使用,大大減少了數(shù)據(jù)庫開發(fā)人員的工作量。通常存儲過程編譯一次,可以執(zhí)行多次,因此也大大的提高了效率。

存儲過程有以下優(yōu)點:

  • 簡化操作,將重復(fù)性很高的一些操作,封裝到一個存儲過程中,簡化了對這些 SQL 的調(diào)用
  • 批量處理,SQL + 循環(huán),減少流量,也就是“跑批”
  • 統(tǒng)一接口,確保數(shù)據(jù)的安全
  • 一次編譯多次執(zhí)行,提高了效率。

以 MySQL 為例,假如要刪除數(shù)據(jù)的表結(jié)構(gòu)如下:

mysql> SHOW CREATE TABLE person;
+--------+---------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                    |
+--------+---------------------------------------------------------------------------------------------------------------------------------+
| person | CREATE TABLE `person` (
  `age` int(11) DEFAULT NULL,
  `inserttime` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+---------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

創(chuàng)建一個名為 person 的表,其中 inserttime 字段為 datetime 類型,我們用 inserttime 字段存儲數(shù)據(jù)的生成時間。

創(chuàng)建一個刪除指定表數(shù)據(jù)的存儲過程,如下:

mysql> delimiter //
mysql> CREATE PROCEDURE del_data(IN `date_inter` int)
    -> BEGIN
    ->   DELETE FROM person WHERE inserttime < date_sub(curdate(), interval date_inter day);
    -> END //
mysql> delimiter ;

創(chuàng)建一個名為 del_data 的存儲過程,參數(shù) date_inter 指定要刪除的數(shù)據(jù)距離當(dāng)前時間的天數(shù)。當(dāng)表 person 的 inserttime 字段值(datetime 類型)加上參數(shù) date_inter 天小于當(dāng)前時間,則認(rèn)為數(shù)據(jù)過期,將過期的數(shù)據(jù)刪除。

事件(event)

事件是在相應(yīng)的時刻調(diào)用的過程式數(shù)據(jù)庫對象。一個事件可調(diào)用一次,也可周期性的啟動,它由一個特定的線程來管理,也就是所謂的“事件調(diào)度器”。
事件和觸發(fā)器類似,都是在某些事情發(fā)生的時候啟動。當(dāng)數(shù)據(jù)庫上啟動一條語句的時候,觸發(fā)器就啟動了,而事件是根據(jù)調(diào)度事件來啟動的。由于它們彼此相似,所以事件也稱為臨時性觸發(fā)器。事件調(diào)度器可以精確到每秒鐘執(zhí)行一個任務(wù)。

如下創(chuàng)建一個事件,周期性的在某個時刻調(diào)用存儲過程,來進(jìn)行清理數(shù)據(jù)。

mysql> CREATE EVENT del_event  
    ->     ON SCHEDULE 
    ->     EVERY 1 DAY 
    ->     STARTS '2020-03-20 12:00:00'
    ->     ON COMPLETION PRESERVE ENABLE
    ->     DO CALL del_data(1);

創(chuàng)建一個名為 del_event 的事件,該事件從 2020-03-20 開始,每天的 12:00:00 執(zhí)行存儲過程 del_data(1)。

然后執(zhí)行:

mysql> SET global event_scheduler = 1;

打開事件。這樣事件 del_event 就會在指定的時間自動在后臺執(zhí)行。通過上述的存儲過程 del_data 和事件 del_event,來達(dá)到定時自動刪除過期數(shù)據(jù)的目的。

TTL(Time To Live) 清洗數(shù)據(jù)

通過上述存儲過程和事件的組合可以定時清理數(shù)據(jù)庫中的過期數(shù)據(jù)。圖數(shù)據(jù)庫 Nebula Graph 提供了 更加簡單高效的方式—使用 TTL 的方式來自動清洗過期數(shù)據(jù)。

使用 TTL 方式自動清洗過期數(shù)據(jù)的好處如下:

  1. 簡單方便
  2. 通過數(shù)據(jù)庫系統(tǒng)內(nèi)部邏輯進(jìn)行處理,安全可靠
  3. 數(shù)據(jù)庫會根據(jù)自身的狀態(tài)自動判斷是否需要處理,如果需要處理,將在后臺自動進(jìn)行處理,無需人工干預(yù)。

TTL 簡介

TTL,全稱 Time To Live,用來指定數(shù)據(jù)的生命周期,數(shù)據(jù)時效到期后這條數(shù)據(jù)會被自動刪除。在圖數(shù)據(jù)庫 Nebula Graph 中,我們實現(xiàn) TTL 功能,用戶設(shè)置好數(shù)據(jù)的存活時間后,在預(yù)定時間內(nèi)系統(tǒng)會自動從數(shù)據(jù)庫中刪除過期的點或者邊。

在 TTL 中,過期數(shù)據(jù)會在下次 compaction 時被刪除,在下次 compaction 之前,query 會過濾掉過期的點和邊。

圖數(shù)據(jù)庫 Nebula Graph 的 TTL 功能需 ttl_colttl_duration 兩個字段一起使用,到期閾值是 ttl_col 指定的屬性對應(yīng)的值加上 ttl_duration 設(shè)置的秒數(shù)。其中 ttl_col 指定的字段的類型應(yīng)為 integer 或 timestamp,ttl_duration 的計量單位為秒。

TTL 讀過濾

針對 tag / edge,Nebula Graph 在 TTL 中將讀數(shù)據(jù)過濾邏輯下推到 storage 層進(jìn)行處理。在 storage 層,首先獲取該 tag / edge 的 TTL 信息,然后依次遍歷每個頂點或邊,取出 ttl_col 字段值,根據(jù) ttl_duration 的值加上 ttl_col 列字段值,跟當(dāng)前時間的時間戳進(jìn)行比較,判斷數(shù)據(jù)是否過期,過期的數(shù)據(jù)將被忽略。

TTL compaction

RocksDB 文件組織方式

圖數(shù)據(jù)庫 Nebula Graph 底層存儲使用的是 RocksDB,RocksDB 在磁盤上的文件是分為多層的,默認(rèn)是 7 層,如下圖所示:

圖數(shù)據(jù)庫 Nebula Graph TTL 特性

SST文件在磁盤上的組織方式

Level 0 層包含的文件,是由內(nèi)存中的 Memtable flush 到磁盤,生成的 SST 文件,單個文件內(nèi)部按 key 有序排列,文件之間無序。其它 Level 上的多個文件之間都是按照 key 有序排列,并且文件內(nèi)也有序,如下圖所示:

圖數(shù)據(jù)庫 Nebula Graph TTL 特性

非Level 0 層的文件數(shù)據(jù)劃分

RocksDB compaction 原理

RocksDB 是基于 LSM 實現(xiàn),但 LSM 并不是一個具體的數(shù)據(jù)結(jié)構(gòu),而是一種數(shù)據(jù)結(jié)構(gòu)的概念和設(shè)計思想,具體細(xì)節(jié)參考 LSM論文。而 LSM 中最重要部分就是 compaction,由于數(shù)據(jù)文件采用 Append only 方式寫入,而對于過期的數(shù)據(jù),重復(fù)的、已刪除的數(shù)據(jù),需要通過 compaction 進(jìn)行逐步的清理。

RocksDB compaction 邏輯

我們采用的 RocksDB 的 compaction 策略為 Level compaction。當(dāng)數(shù)據(jù)寫到
RocksDB 時,會先將數(shù)據(jù)寫入到一個 Memtable 中,當(dāng)一個 Memtable 寫滿之后,就會變成 Immutable 的 Memtable。RocksDB 在后臺通過一個 flush 線程將這個 Memtable flush 到磁盤,生成一個 Sorted String Table (SST) 文件,放在 Level 0 層。當(dāng) Level 0 層的 SST 文件個數(shù)超過閾值之后,就會與Level 1 層進(jìn)行 compaction。通常必須將 Level 0 的所有文件 compaction 到 Level 1 中,因為 Level 0 的文件的 key 是有交疊的。

Level 0 與 Level 1 的 compaction 如下:

圖數(shù)據(jù)庫 Nebula Graph TTL 特性

Level 0 與 Level 1 的 compaction

其他 Level 的 compaction 規(guī)則一樣,以 Level 1與 Level 2 的 compaction 為例進(jìn)行說明,如下所示:

圖數(shù)據(jù)庫 Nebula Graph TTL 特性

Level 1 與 Level 2 的 compaction

當(dāng) Level 0 compaction 完成后,Level 1 的文件總大小或者文件數(shù)量可能會超過閾值,觸發(fā) Level 1 與 Level 2 的 compaction。從 Level 1 層至少選擇一個文件 compaction 到 Level 2 的 key 重疊的文件中。compaction 后可能會觸發(fā)下一個 Level 的 compaction,以此類推。

如果沒有 compaction,寫入是非??斓模@樣會造成讀性能降低,同樣也會造成很嚴(yán)重的空間放大問題。為了平衡寫入、讀取、空間三者的關(guān)系,RocksDB 會在后臺執(zhí)行 compaction,將不同 Level 的 SST 進(jìn)行合并。

TTL compaction 原理

除了上述默認(rèn)的compaction操作外(sst文件合并),RocksDB 還提供了CompactionFilter 功能,可以讓用戶自定義個性化的compaction邏輯。Nebula Graph 使用了這個CompactionFilter來定制本文討論的TTL功能。該功能是 RocksDB 在 compaction 過程中,每讀取一條數(shù)據(jù)時,都會調(diào)用一個定制的Filter 函數(shù)。TTL compaction 的實現(xiàn)方法就是在 Filter 函數(shù)中實現(xiàn) TTL 過期數(shù)據(jù)刪除邏輯,具體如下:

  1. 首先獲取 tag / edge 的 TTL 信息
  2. 然后遍歷每個頂點或邊數(shù)據(jù),取出 ttl_col 列字段值
  3. 根據(jù) ttl_duration 的值加上 ttl_col 列字段值,跟當(dāng)前時間的時間戳進(jìn)行比較,然后判斷數(shù)據(jù)是否過期,過期的數(shù)據(jù)將被刪除。

TTL 用法

在圖數(shù)據(jù)庫 Nebula Graph 中,edge 和 tag 實現(xiàn)邏輯一致,在這里僅以 tag 為例,來介紹 Nebula Graph 中 TTL 用法。

創(chuàng)建 TTL 屬性

Nebula Graph 中使用 TTL 屬性分為兩種方式:

create tag 時指定 ttl_duration 來表示數(shù)據(jù)的持續(xù)時間,單位為秒。ttl_col 指定哪一列作為 TTL 列。語法如下:

nebula> CREATE TAG t (id int, ts timestamp ) ttl_duration=3600, ttl_col="ts";

當(dāng)某一條記錄的 ttl_col 列字段值加上 ttl_duration 的值小于當(dāng)前時間的時間戳,則該條記錄過期,否則該記錄不過期。

  • ttl_duration 的值為非正數(shù)時,則點的此 tag 屬性不會過期
  • ttl_col 只能指定類型為 int 或者 timestamp 的列名。

或者 create tag 時沒有指定 TTL 屬性,后續(xù)想使用 TTL 功能,可以使用 alter tag 來設(shè)置 TTL 屬性。語法如下:

nebula> CREATE TAG t (id int, ts timestamp );
nebula> ALTER TAG t ttl_duration=3600, ttl_col="ts";

查看 TTL 屬性

創(chuàng)建完 tag 可以使用以下語句查看 tag 的 TTL 屬性:

nebula> SHOW CREATE TAG t;
=====================================
| Tag | Create Tag                  |
=====================================
| t   | CREATE TAG t (
  id int,
  ts timestamp
) ttl_duration = 3600, ttl_col = id |
-------------------------------------

修改 TTL 屬性

可以使用 alter tag 語句修改 TTL 的屬性:

nebula> ALTER TAG t ttl_duration=100, ttl_col="id";

刪除 TTL 屬性

當(dāng)不想使用 TTL 屬性時,可以刪除 TTL 屬性:

可以設(shè)置 ttl_col 字段為空,或刪除配置的 ttl_col 字段,或者設(shè)置 ttl_duration 為 0 或者 -1。

nebula> ALTER TAG t1 ttl_col = ""; -- drop ttl attribute

刪除配置的 ttl_col 字段:

nebula> ALTER TAG t1 DROP (a); -- drop ttl_col

設(shè)置 ttl_duration 為 0 或者 -1:

nebula> ALTER TAG t1 ttl_duration = 0; -- keep the ttl but the data never expires

舉例

下面的例子說明,當(dāng)使用 TTL 功能,并且數(shù)據(jù)過期后,查詢該 tag 的數(shù)據(jù)時,過期的數(shù)據(jù)被忽略。

nebula> CREATE TAG t(id int) ttl_duration=100, ttl_col="id";
nebula> INSERT VERTEX t(id) values 102:(1584441231);
nebula> FETCH prop on t 102;
Execution succeeded (Time spent: 5.945/7.492 ms)

注意:

  1. 當(dāng)某一列作為 ttl_col 值的時候,不允許 change 該列。
    必須先移除 TTL 屬性,再 change 該列。
  2. 對同一 tag,index 和 TTL 功能不能同時使用。即使 index 和 TTL 創(chuàng)建于不同列,也不可以同時使用。

edge 同 tag 的邏輯一樣,這里就不在詳述了。

TTL 的介紹就到此為止了,如果你對圖數(shù)據(jù)庫 Nebula Graph 的 TTL 有改進(jìn)想法或其他要求,歡迎去 GitHub: https://github.com/vesoft-inc/nebula issue 區(qū)向我們提 issue 或者前往官方論壇: https://discuss.nebula-graph.io/ 的 Feedback 分類下提建議 ????

作者有話說:Hi,我是 panda sheep,是圖數(shù)據(jù)庫 Nebula Graph 研發(fā)工程師,對數(shù)據(jù)庫領(lǐng)域非常感興趣,也有自己的一點點心得,希望寫的經(jīng)驗分享能給大家?guī)韼椭缬胁划?dāng)之處也希望能幫忙糾正,謝謝~

網(wǎng)站題目:圖數(shù)據(jù)庫NebulaGraphTTL特性
本文路徑:http://muchs.cn/article2/ipgeoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站、網(wǎng)站建設(shè)、定制網(wǎng)站、微信公眾號、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司