婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > EventStore文件存儲設計詳解

EventStore文件存儲設計詳解

熱門標簽:揭陽外呼系統公司 鄭州中國移動400電話申請 地圖標注審核工作怎么樣注冊 無錫電銷機器人銷售 招聘信息 去哪里辦卡 熱血傳奇沃瑪森林地圖標注 地圖標注植物名稱 南召400電話辦理資費 福建ai電銷機器人加盟公司

背景

ENode是一個CQRS+Event Sourcing架構的開發框架,Event Sourcing需要持久化事件,事件可以持久化在DB,但是DB由于面向的是CRUD場景,是針對數據會不斷修改或刪除的場景,所以內部實現會比較復雜,性能也相對比較低。而Event Store實際上對數據只有新增和查詢的需求,所以我想為Event Sourcing的場景針對性的實現一個Event Store。看了一下業界的一些實現,感覺都沒有達到我的期望,所以想自己動手實現一個。下面是我構思的一個Event Store的單機版應該要具備的能力以及對應的設計方案,分享出來和大家討論。

一、需求概述

•存儲聚合根的事件數據
•支持事件的版本并發控制,新事件的版本號必須是當前版本號+1
•支持命令重復判斷,即不可以處理重復命令產生的事件
•支持按聚合根ID查詢該聚合根的所有事件
•支持按聚合根ID+事件版本號查詢指定的事件
•支持按命令ID查詢該命令對應的事件數據
•高性能,寫入要盡量快,查詢要盡量快

二、事件數據格式

{
 "aggregateRootId": "",   //聚合根ID
 "aggregateRootType": "",  //聚合根類型
 "eventVersion": "",    //事件版本號
 "eventTime": "",      //事件發生時間
 "eventData": "",      //事件數據,JSON格式
 "commandId": "",      //產生該事件的命令ID
 "commandTime": ""     //產生該事件的命令產生時間
}

三、存儲設計

1、核心內存存儲設計

•遵循內存只存儲索引數據的原則,盡量充分利用內存;
•aggregateLatestVersionDict,存儲每個聚合根的最大事件版本號 ◦key:aggregateRootId,聚合根ID
◦value: ◦eventVersion,當前聚合根的最新事件的版本號,也即當前聚合根的版本號
◦eventTime,事件產生時間
◦eventPosition,事件在事件數據文件中的位置

•commandIdDict,存儲命令索引 ◦key:commandId,命令ID
◦value: ◦commandTime,命令產生時間
◦eventPosition,命令對應的事件在事件數據文件中的位置

2、物理存儲的數據

•事件數據:eventData,單條數據的結構:

{
 "aggregateRootId": "",   //聚合根ID
 "aggregateRootType": "",  //聚合根類型
 "eventVersion": "",    //事件版本號
 "eventTime": "",      //事件發生時間
 "eventData": "",      //事件數據,JSON格式
 "commandId": "",      //產生該事件的命令ID
 "commandTime": "",     //產生該事件的命令產生的事件
 "previousEventPosition": ""http://前一個事件在事件文件中的位置
}

•事件索引:eventIndex,單條數據的結構:

{
 "aggregateRootId": "",   //聚合根ID
 "eventVersion": "",    //事件版本號
 "eventTime": "",      //事件產生時間
 "eventPosition": "",    //事件在事件數據文件中的位置
}

•命令索引:commandIndex,存儲內容:存儲所有命令的ID及其對應的事件所在文件的位置

{
 "commandId": "",    //聚合根ID
 "commandTime": "",   //命令產生時間
 "eventPosition": "",  //事件在事件數據文件中的位置
}

3、事件數據存儲

•同步順序寫eventDataChunk文件,一個文件大小為1GB,寫滿一個文件后寫入下一個文件;
•寫入每個事件時,同時寫入當前事件的前一個事件所在的文件位置,以便將來可以一次性將某個聚合根的所有事件從文件查找出來;

4、事件索引存儲

•異步順序寫eventIndexChunk文件,一個文件大小為1GB,寫滿一個文件后寫入下一個文件;
•對于已經寫滿的不會再變化的文件的內容,使用后臺線程進行B+樹索引整理,索引的排序依據是聚合根ID+事件版本號;B+樹設計為3層,根節點包含1000個子節點,每個子節點再包含1000個子節點,這樣葉子節點共有100W個。每個葉子節點我們保存20個版本索引,則單個文件共可保存最多2000W個版本索引,10個文件為2億個版本索引;單機存儲2億個事件索引,應該可以滿足大部分應用場景了;3層,則查找任意一個節點,只需要3次IO訪問;
•由于是后臺線程對已經寫完的文件進行B+樹索引整理,B+樹是在內存建立,建立完成后,將最新的內容寫入新文件,原子替換老的eventIndexChunk文件;所以,這塊的邏輯處理應該不會對服務的主邏輯產生較大的影響;
•采用BloomFilter優化查詢性能,使用BloomFilter來快速判斷某個eventIndexChunk文件中是否包含某個聚合根ID,如果不在,則不用從B+樹去檢索該聚合根的版本號了;如果在,則取檢索;通過這個設計,當我們要獲取某個聚合根的最大版本號時,不需要對每個eventIndexChunk文件進行B+樹查詢,而是先通過BloomFilter快速判斷當前的eventIndexChunk文件是否包含該聚合根的信息,大大提升檢索效率;BloomFilter的二進制Bit數據占用內存小,可以在每個eventIndexChunk文件被掃描時,和文件頭的信息一起加載到內存;

5、命令索引存儲

•異步順序寫commandIndexChunk文件,一個文件大小為1GB,寫滿一個文件后寫入下一個文件;
•同事件索引存儲,進行B+樹索引建立,索引的排序依據是命令ID;
•同事件索引存儲,采用BloomFilter優化查詢性能;

四、框架邏輯設計

1、查詢某個聚合根的最大版本號

•EventStore啟動時,會加載所有的eventIndexChunk文件的元數據到內存,比如文件號、文件頭、BloomFilter等信息,但不真實加載文件內容,文件數不會太多,最多也就幾十個;
•根據聚合根ID+BloomFilter算法,快速確定應該到哪個eventIndexChunk文件中去查找該聚合根的最新版本號,eventIndexChunk文件從新到舊遍歷,因為某個聚合根ID的最大版本號一定是在最新的eventIndexChunk文件中的;
•在找到的eventIndexChunk中使用B+樹查找算法,找到對應的葉子節點;
•在找到的葉子節點,使用二分查找算法(由于單個節點的聚合根ID不多,順序查找即可),找到指定聚合根的最新版本號;

2、查詢某個聚合根的所有事件

•先通過上面的算法找出該聚合根的最大版本號的事件在事件數據文件中的位置;
•然后從該位置獲取事件完整數據;
•再根據事件數據中記錄的上一個事件在事件數據文件中的位置,查找上一個事件的數據;
•以此類推,直到找到該聚合根的第一個事件的數據;

3、查詢某個命令對應的事件數據

•先嘗試從內存查詢該命令的索引信息,如果存在,則直接獲取該命令對應的事件在事件數據文件中的位置,即eventPosition;如果不存在,則嘗試從命令的索引文件中查找,結合BloomFilter和B+樹查找算法進行查找;
•如果找到了eventPosition,則根據eventPosition到事件數據文件中查找對應的事件數據即可;如果未找到,則返回空;

4、追加一個新事件的處理邏輯

•根據aggregateLatestVersionDict判斷事件版本號是否合法,必須是聚合根的當前版本號+1,如果當前版本號不存在,則首先嘗試從eventIndexChunk文件查找當前聚合根的最大版本號,如果還是查找不到,說明當前聚合根確實不存在任何事件,則當前事件版本號必須為1;
•根據commandIdDict判斷命令ID是否重復,如果commandIdDict中不存在該命令,嘗試從commandIndexChunk文件中查找,也是B+樹的方式;這里需要設計一個配置項,讓開發者配置是否需要繼續從commandIndexChunk文件查找命令ID。有時我們只希望從內存查找即可,不希望再從磁盤查找了,因為判斷命令是否重復我們很多時候只希望檢查最近一段時間內的命令,檢查全部命令代價過大,意義也不是很大;
•如果事件的版本號合法、命令ID不重復,則Append的方式寫入事件數據到eventDataChunk;
•寫入完成后,更新aggregateLatestVersionDict、commandIdDict,、BloomFilter的Bit數組,以及將當前的事件放入內存的一個雙緩沖隊列;隊列消費者異步批量將事件索引和命令索引寫入對應的索引文件;
•返回事件寫入結果;

5、其他邏輯

•異步線程定時批量持久化事件索引;
•異步線程定時批量持久化命令索引;
•異步線程定時清理不需要放在內存的聚合根最新版本號信息(aggregateLatestVersionDict中的key),根據eventTime判斷,只保留最近1周有過變化(產生過事件)的聚合根;
•異步線程定時清理不需要放在內存的命令索引(commandIdDict中的key),根據commandTime判斷,只保留最近1周的命令ID;
•異步線程定時進行事件索引和命令索引的B+樹索引的建立,即對已經寫入完成的eventIndexChunk和commandIndexChunk文件的內部重構;
•eventIndexChunk和commandIndexChunk文件標記為寫入完成前,要把BloomFilter的Bit數組內容寫入文件中;
•其他EventStore的啟動邏輯,比如啟動時加載一定數量的索引數據到內存,以及索引數據相比事件數據是否有漏掉或無效的檢查;
•其他邏輯支持,如支持聚合根的快照存儲,從文件查找數據時,如果文件的B+樹索引信息還未建立,則需要進行全文掃碼;

總結

以上所述是小編給大家介紹的EventStore文件存儲設計詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

您可能感興趣的文章:
  • PHP實現抓取百度搜索結果頁面【相關搜索詞】并存儲到txt文件示例
  • numpy的文件存儲.npy .npz 文件詳解
  • 詳解如何在python中讀寫和存儲matlab的數據文件(*.mat)
  • 詳解MySQL中InnoDB的存儲文件
  • Android開發實現讀取Assets下文件及文件寫入存儲卡的方法
  • MySQL數據文件存儲位置的查看方法

標簽:南昌 鹽城 東莞 景德鎮 桂林 宣城 黔南 文山

巨人網絡通訊聲明:本文標題《EventStore文件存儲設計詳解》,本文關鍵詞  EventStore,文件,存儲,設計,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《EventStore文件存儲設計詳解》相關的同類信息!
  • 本頁收集關于EventStore文件存儲設計詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    麻豆精品一二三| 色综合色综合色综合 | 日韩欧美一区中文| 中文字幕中文字幕在线一区 | 亚洲一区二区五区| 国产精品1区2区| 欧美人与性动xxxx| 亚洲人吸女人奶水| 夫妻av一区二区| 91精品国产全国免费观看| 亚洲色图第一区| 波多野洁衣一区| 久久只精品国产| 老司机午夜精品99久久| 日本久久一区二区三区| 亚洲国产精品激情在线观看| 美国十次了思思久久精品导航| 欧美性xxxxxx少妇| 亚洲天堂精品在线观看| 成人黄色一级视频| 国产欧美日韩视频一区二区| 免费黄网站欧美| 欧美午夜精品免费| 亚洲国产精品久久人人爱蜜臀| av激情成人网| 国产精品久久久久精k8| 国产福利91精品一区二区三区| 精品国精品自拍自在线| 久久99蜜桃精品| 久久免费看少妇高潮| 激情综合色综合久久综合| 精品91自产拍在线观看一区| 久久97超碰色| 久久久蜜桃精品| 丁香另类激情小说| 国产精品国产三级国产普通话99 | 亚洲成人福利片| 色婷婷精品久久二区二区蜜臀av| 亚洲色图欧洲色图| 欧美日韩中文字幕一区二区| 亚洲国产va精品久久久不卡综合| 欧美日韩国产色站一区二区三区| 性感美女久久精品| 日韩欧美不卡在线观看视频| 精品一区二区三区久久| 国产日本亚洲高清| av激情亚洲男人天堂| 亚洲综合色在线| 欧美一区二区性放荡片| 国产在线视视频有精品| 中日韩av电影| 欧美日韩国产综合一区二区三区| 免费精品视频在线| 中文字幕巨乱亚洲| 欧美视频在线播放| 韩国欧美国产一区| 亚洲天堂av老司机| 欧美一级欧美三级| 高清在线不卡av| 亚洲成人一二三| 久久九九全国免费| 欧美三级电影在线观看| 久久不见久久见免费视频7 | 色综合久久88色综合天天| 午夜亚洲福利老司机| 国产亚洲女人久久久久毛片| 在线观看成人小视频| 毛片不卡一区二区| 亚洲精品菠萝久久久久久久| 日韩免费电影网站| 成+人+亚洲+综合天堂| 日韩黄色免费网站| 1024成人网色www| 欧美成人国产一区二区| 91久久精品一区二区二区| 久久精品国产亚洲5555| 亚洲专区一二三| 国产欧美一区在线| 日韩一级高清毛片| 欧美自拍偷拍一区| 成人网页在线观看| 精品写真视频在线观看| 亚洲一区免费视频| 国产精品成人免费在线| 欧美精品一区二区三区很污很色的| 91在线精品秘密一区二区| 激情另类小说区图片区视频区| 一区二区三区毛片| 国产精品国产a| 国产欧美日韩另类一区| 日韩免费观看2025年上映的电影| 欧美性一区二区| 99久久免费视频.com| 国产精品1区2区| 国产主播一区二区| 午夜精品成人在线| 亚洲国产另类精品专区| 亚洲欧美另类小说| 亚洲天堂av一区| 日韩一区在线免费观看| 国产精品午夜久久| 国产日韩成人精品| 国产日本欧美一区二区| 国产日韩亚洲欧美综合| 国产丝袜在线精品| 日本一二三不卡| 国产精品另类一区| 国产精品高潮呻吟久久| 综合网在线视频| 亚洲欧洲国产日本综合| 亚洲特级片在线| 一区二区三区精品| 香蕉成人啪国产精品视频综合网| 一区二区久久久| 午夜精品久久久久久久99水蜜桃| 午夜av区久久| 麻豆精品国产传媒mv男同| 在线播放亚洲一区| 91精品欧美一区二区三区综合在| 欧美一区二区网站| 欧美不卡一区二区三区四区| 精品欧美一区二区在线观看| 精品国免费一区二区三区| 国产农村妇女毛片精品久久麻豆| 国产精品国产成人国产三级| 亚洲欧美日韩一区二区| 亚洲大片在线观看| 久久99国内精品| 成人综合在线观看| 在线视频亚洲一区| 欧美一级xxx| 国产欧美一区二区精品忘忧草| 国产精品白丝在线| 午夜精彩视频在线观看不卡| 久久精品国内一区二区三区| 国产成人精品影院| 欧美在线免费观看视频| 日韩午夜激情av| 国产精品久久久久久亚洲毛片| 亚洲韩国一区二区三区| 日韩激情一区二区| 国产成人综合亚洲网站| 欧美性猛交xxxxxx富婆| 欧美v日韩v国产v| 亚洲欧洲国产专区| 免费成人在线播放| 成人av在线观| 欧美xxxxxxxxx| 亚洲精品成人精品456| 精品制服美女丁香| 在线观看一区二区视频| 久久夜色精品一区| 亚洲在线中文字幕| 国产精品一级黄| 欧美美女喷水视频| 国产精品久久三| 免费高清在线一区| 欧洲视频一区二区| 国产日韩精品一区| 久久成人免费网站| 欧美日韩亚洲综合一区 | 人禽交欧美网站| 91在线观看下载| 精品处破学生在线二十三| 五月综合激情日本mⅴ| www.日本不卡| 国产午夜精品一区二区三区嫩草| 亚洲成av人片在线观看| 97精品久久久久中文字幕| 精品动漫一区二区三区在线观看| 亚洲国产精品久久久久婷婷884 | 一区二区三区精品在线| 国产精品自在在线| 精品少妇一区二区三区视频免付费| 一区二区三区国产精华| 99久久99久久免费精品蜜臀| 久久精品夜色噜噜亚洲a∨| 男女性色大片免费观看一区二区| 欧美在线看片a免费观看| 亚洲少妇30p| 99久久精品情趣| 国产精品视频免费| 国产成人精品免费网站| 久久久噜噜噜久久人人看 | 首页欧美精品中文字幕| 91免费在线播放| 中文字幕一区在线观看视频| 成人免费视频视频在线观看免费| 国产亚洲1区2区3区| 国产一区在线视频| 精品国产一区二区国模嫣然| 另类小说图片综合网| 日韩欧美国产综合| 国内精品视频一区二区三区八戒| 欧美一级xxx| 国产在线视频一区二区| 久久久久综合网| av电影在线观看完整版一区二区| 国产精品久久久久久久久晋中| 99久久精品国产导航|