婷婷综合国产,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
    国产制服丝袜一区| 欧美日韩一区二区电影| 欧美午夜电影网| 国产999精品久久久久久| 日韩成人一级大片| 欧美精品久久天天躁| 日韩亚洲国产中文字幕欧美| 国产一区二区三区免费| 成人午夜视频在线| 日韩一级二级三级| 丁香亚洲综合激情啪啪综合| 99精品久久免费看蜜臀剧情介绍| 偷拍日韩校园综合在线| 热久久免费视频| 精品一区二区三区久久久| 精品在线免费视频| 日韩限制级电影在线观看| 亚洲午夜av在线| 日韩一区二区三| 欧美精品欧美精品系列| 国产精品国产三级国产有无不卡| 亚洲免费三区一区二区| 国产欧美精品一区二区色综合| 666欧美在线视频| 91麻豆高清视频| 91在线观看高清| 99久久国产综合精品女不卡| 日韩1区2区3区| 国产精品一区二区视频| 成人av午夜影院| 久久精品免视看| 一区二区三区免费看视频| 国产成人免费在线| 欧美一卡二卡三卡四卡| 欧美国产精品中文字幕| 欧美性大战久久| 成人爽a毛片一区二区免费| 天天影视网天天综合色在线播放| 亚洲色图丝袜美腿| 不卡高清视频专区| 亚洲欧美日韩国产一区二区三区| 欧美唯美清纯偷拍| 欧美一区二区三区在| 亚洲五码中文字幕| 国产精品成人一区二区艾草 | 蜜桃精品视频在线观看| 91在线一区二区| 精东粉嫩av免费一区二区三区| 欧美精品一区二区三| 欧美三级视频在线观看| 亚洲欧美在线视频观看| 26uuu国产电影一区二区| 欧美精品久久99| 欧美性大战久久久久久久| www.爱久久.com| 国产精品三级av| 久久99久久精品| 91成人国产精品| 亚洲一区二区三区四区五区黄| 日本网站在线观看一区二区三区 | 欧美三级三级三级爽爽爽| 中文字幕av一区 二区| 欧美激情艳妇裸体舞| 欧美中文字幕一区二区三区亚洲| 亚洲精品欧美激情| 在线91免费看| 亚洲青青青在线视频| 欧美日韩在线播放三区| 五月天欧美精品| 日韩欧美中文一区| 亚洲国产精品一区二区久久| 色8久久精品久久久久久蜜 | 国产精品久久福利| 欧美在线综合视频| 91精品国产色综合久久不卡电影| 日韩av一区二| 久久国产人妖系列| 国产成人在线看| 亚洲欧美日韩中文播放| 成人午夜看片网址| 亚洲在线视频网站| 精品国产91洋老外米糕| 免费黄网站欧美| 中文字幕色av一区二区三区| 亚洲精品乱码久久久久久久久| 一区二区在线免费| 视频一区二区欧美| 久久在线观看免费| 国产精品亚洲人在线观看| 成人黄色av网站在线| 亚洲免费高清视频在线| 亚洲免费在线观看| 欧美高清在线一区| 亚洲男人的天堂网| 欧美日韩国产高清一区二区三区| 欧美色区777第一页| 亚洲日本乱码在线观看| 国产精品久久夜| 成人午夜在线播放| 欧美丝袜第三区| 亚洲一卡二卡三卡四卡无卡久久| 日韩欧美美女一区二区三区| 91精选在线观看| 欧美日韩一级黄| 9人人澡人人爽人人精品| 亚洲精品一区二区三区福利| 欧美成人一区二区三区在线观看| 伊人开心综合网| 亚洲国产aⅴ天堂久久| 婷婷久久综合九色综合绿巨人 | 专区另类欧美日韩| 日本一区二区视频在线观看| 久久久久亚洲蜜桃| 国产一区二三区| 国产精品麻豆欧美日韩ww| 丝袜亚洲另类欧美综合| 日韩丝袜美女视频| 欧美精品久久久久久久多人混战 | 国产在线精品一区二区夜色| 精品成人在线观看| 欧美专区日韩专区| 国产精品一区二区三区网站| 国产高清精品网站| 日韩一区二区影院| 成人在线一区二区三区| 色婷婷av一区二区三区gif| 91国产丝袜在线播放| 成人午夜大片免费观看| 欧美一区二区三区免费观看视频| 国产精品激情偷乱一区二区∴| 国精产品一区一区三区mba桃花| 亚洲成人福利片| 欧美午夜理伦三级在线观看| 欧美精品自拍偷拍动漫精品| 国产91在线观看| 亚洲日本电影在线| 91激情五月电影| 国产亚洲1区2区3区| 91精品国产乱码久久蜜臀| 欧美精品第1页| 精品一区二区av| 欧美精品免费视频| 欧美日韩一区二区在线视频| 久久亚洲捆绑美女| 国产精品白丝在线| 一本在线高清不卡dvd| 欧美国产日韩精品免费观看| 亚洲一区二区三区免费视频| 欧美一级高清片| 538prom精品视频线放| 日韩欧美在线不卡| 国产欧美视频一区二区| 亚洲最大色网站| 99麻豆久久久国产精品免费优播| 精品视频免费看| 久久婷婷综合激情| 国产尤物一区二区| 韩国精品一区二区| 成人免费视频一区| 国产成人免费9x9x人网站视频| 一区二区三区美女视频| 99精品视频免费在线观看| 亚洲自拍偷拍麻豆| 久久99精品久久只有精品| 粉嫩av一区二区三区在线播放 | 欧洲生活片亚洲生活在线观看| 亚洲一卡二卡三卡四卡无卡久久| 秋霞午夜鲁丝一区二区老狼| 99综合电影在线视频| 91精品在线一区二区| 欧美精品一区二区蜜臀亚洲| 精品sm捆绑视频| 久久亚洲私人国产精品va媚药| 中文字幕高清不卡| 午夜久久久久久久久久一区二区| 91丨porny丨中文| 久久精品亚洲麻豆av一区二区| 午夜私人影院久久久久| 在线影院国内精品| 一区二区三区国产| 国产一区二区h| 亚洲日本免费电影| 日韩手机在线导航| 国产成人三级在线观看| 一区二区理论电影在线观看| 久久99国产精品免费| heyzo一本久久综合| 国产精品乡下勾搭老头1| 成人av资源网站| 国产精品久久久久久久久久久免费看 | aaa国产一区| 国产在线一区二区综合免费视频| 最新国产の精品合集bt伙计| 日韩欧美亚洲另类制服综合在线| 国产精一区二区三区| 国产精品一区二区在线看| 成人免费不卡视频| 99精品视频一区二区| 麻豆国产欧美日韩综合精品二区| 成人三级伦理片|