关于实现一个基于文件持久化的EventStore的核心构思

  • 时间:
  • 浏览:1
  • 来源:大发彩票快三—大发彩票app

在调研的过程中,无意中发现LevelDB的插入性能非常高。它是由Google的MapReduce和BigTable的作者设计的一俩个 基于key/value底部形态的轻量级的非常高效的开源的NoSQL数据库。它并能支持10亿级别的数据量存储。LevelDB 是单守护程序运行运行的服务,性能非常之高,在一台一俩个 Q6800的CPU机器上,每秒钟写数据超过40w,而随机读的性能每秒钟超过10w,足见性能之高。正肯能他的高效,所以有现在所以有某些NoSQL都使用它来作为底层的数据持久化,比如淘宝的Tair支持用LevelDB来持久化缓存数据。所以有有时间研究下LevelDB的设计与实现非常有必要。而是LevelDB只提供最简单的key/value的操作。对于顺序插入事件的需求,时会 调用LevelDB的put操作。而是这里的put操作不支持并发冲突的检测,也所以 肯能连续put了一俩个 key相同的value,则前一俩个 value就会被后一俩个 value所覆盖,这是是否是亲戚亲戚让一群人 我应该 的。所以有亲戚亲戚让一群人 肯能使用LevelDB,对于同一俩个 聚合根时会 了一俩个 版本号相同的事件你这些 需求仍然需要亲戚亲戚让一群人 自己来保证,时会 通过上方DEMO中的思路来实现。也所以 说,亲戚亲戚让一群人 仅仅用LevelDB来代替日志。其实所以 肯能省去亲戚亲戚让一群人 所以有的工作量,肯能亲戚亲戚让一群人 自己写日志以及记录每个事件的存储位置和长度是是否是一件容易的事情,要求对算法和逻辑非常学深悟,而是假使 一俩个 bit错位了,肯能读取出来的所有数据都错了。而LevelDB帮亲戚亲戚让一群人 完成了最僵化 和头疼的事情了。但不幸的是,LevelDB没有官方的windows版本。我应该 找到.net平台下的实现,但要在生产环境使用,还是要多做所以有验证才行。另外,肯能要用LevelDB来持久化事件,所以 们的key时会 是聚合根ID+事件版本号的字符串拼接。这点应该真难理解吧!

而是,亲戚亲戚让一群人 主要要确保的是,对同一俩个 聚合根实例,产生的事件肯能版本号相同,则时会 了有一俩个 事件能保存成功,某些的认为并发冲突,需要告诉组织组织结构有并发冲突了,而是由组织组织结构决定接下来该要怎样做。没有要怎样保证你这些 点呢?

上图中的commitlog文件要花费我上方提到的用来存储事件的文本文件,commitlog在metaq消息队列中是用来存储消息的。index文件要花费用来存储事件在commitlog中的位置和长度。在metaq中,则是用来存储消息在commitlog中的位置和长度。所以有,从存储底部形态的强度来看,metaq的消息存储和eventstore的事件存储的底部形态一致;但不一样的是,metaq在存储消息时,需要做并发控制,所有消息假使 append消息到commitlog即可,所有的index文件也假使 append写入即可,关于metaq具体更全版的设计我还没深入研究,有兴趣的亲戚让一群人 也时会 和我交流。而eventstore则需要对事件的版本号做并发控制,这是最大的区别。另外,实际上,事件的索引信息时会 只需要维护在内存中即可,肯能那些索引信息在eventstore启动时突而是能 通过commitlog还原出来。当然亲戚亲戚让一群人 维护一份Index文件也时会 ,所以 会增加事件持久化时的僵化 度,这里到底是是否是需要你这些 Index文件,我需要再研究下metaq后并能更进一步明确。

经过了一番调研,发现用文件存储事件非常要花费。要确保高性能,亲戚亲戚让一群人 时会 顺序写文件(append),而是随机读文件。难能可贵要随机读文件是肯能在当某些command肯能操作同一俩个 聚合根而遇到并发冲突的所以 ,框架需要获取该聚合根的所有最新的事件,而是通过event sourcing重建出最新的聚合根,而是再重试那些遇到并发冲突的command。经过测试,顺序写文件和随机读文件都非常高效,每秒80W次顺序写和每秒10W次随机读在我的笔记本上是是否是大问題;肯能在enode中,domain是基于in-memory架构的,所以有亲戚亲戚让一群人 很少会从eventstore读取事件。所以有重点是要优化持久化事件的性能。而读事件时会 了在command遇到并发冲突的所以 或系统重启的所以 ,才有肯能需要从eventstore读取事件。所以有每秒10W次随机读取应该是是否是大问題。当然,关于文件要怎样写,见下面的遗留大问題的分析。

从上图时会 看出,开启一俩个 守护程序运行运行,并行操作一俩个 聚合根,每个聚合根产生10个不同版本的事件(事件版本号连续递增),每个事件重复产生10W次,只花了要花费1s时间。另外,最后每个聚合根的当前版本号以及所对应的事件所以是正确的。所以有,时会 看出,性能还不错。一俩个 守护程序运行运行并行外理,每秒时会 外理80W个事件(当然实际肯定没没有高,这里是肯能大次责外理都被CompareExchange妙招判断掉了。所以有,时会 了没并发的情况汇报,才是理想情况汇报下的最快的性能点,肯能每个事件是是否是做持久化和更新当前版本的逻辑,上方的代码主所以 为了验证并发情况汇报下是是否是会产生重复版本的事件你这些 功能。),且能保证不需要持久化重复版本的事件。明天有空把持久化事件替换为真实的写文件流的妙招,看看性能会有十几个 ,理论上假使 写文件流够快,那性能应该依旧很高。

另外一俩个 所以 刷磁盘的大问題。亲戚亲戚让一群人 知道,通过文件流写入数据到文件后,肯能不Flush文件流,那数据有肯能还没刷到磁盘。所以有需要定时Flush文件流,出于性能和可靠性的权衡,取舍定时1s刷一次磁盘,通过异步守护程序运行运行刷盘。实际上,大次责NoSQL产品是是否是没有,比如Redis的fsync时会 指定为每隔1s刷一次AOF日志到磁盘。所以 做唯一的大问題是断电后肯能丢失1s的数据,但你这些 时会 通过在服务器上配置UPS备用电源确保断电后服务器还能工作,来确保断电后还能支持足够的时间确保亲戚亲戚让一群人 把文件流的数据刷到磁盘。所以 既外理性能大问題,并能保证不丢失数据。

前面说到,所有聚合根的事件是是否是顺序的妙招append到同一俩个 文件,append事件到文件你这些 步骤一种生活没妙招检查是是否是有并发冲突,文件时会 了帮亲戚亲戚让一群人 持久化数据,不负责检查是是否是有并发冲突。那要怎样检查并发冲突呢?思路所以 在内存设计一俩个 Dictionary,Dictionary的key为聚合根ID,value保存当前聚合根产生的事件的最大版本号,也所以 最后一俩个 事件的版本号。

这篇文章洋洋洒洒,是是否是思路性的东西,希望亲戚亲戚让一群人 都看不需要枯燥,呵呵。欢迎亲戚亲戚让一群人 提出自己的意见和建议!

亲戚亲戚让一群人 知道enode框架的架构是基于ddd+event sourcing的思想。亲戚亲戚让一群人 持久化的是是否是聚合根的最新情况汇报,所以 聚合根产生的领域事件。最近我在思考要怎样实现一俩个 基于文件的eventstore。目标一俩个 :

1.需要要高性能;

2.支持聚合根事件的并发持久化,要确保单个聚合根实例不需要保存版本号相同的事件;

上方还有一俩个 大问題我还没提及,那所以 光用一俩个 文件来存储所有的事件还不够的,亲戚亲戚让一群人 还需要一俩个 文件存储每个事件在文件中的位置和长度,而是亲戚亲戚让一群人 没妙招知道每个事件存储在文件的哪里。也所以 在当事件写入到文件后,亲戚亲戚让一群人 需要知道当前写入的起始位置,而是亲戚亲戚让一群人 时会 将你这些 起始位置信息再写入到所以 要花费索引作用的文件。你这些 大问題下次有肯能在全版分析吧,总体思路和淘宝开源的高性能分布式消息队列metaq的消息存储架构非常类事。淘宝的metaq难能可贵能高性能,很大一方面导致 也是设计为顺序写文件,随机读文件的思路。如下图所示:

首先,每个聚合根实例有多个事件,每个时刻,每个聚合根肯时会 有产生多个事件而是要保存到eventstore中。为那些呢?肯能亲戚亲戚让一群人 的domain model所在的应用服务器一般是集群部署的,所以有全版有肯能同一俩个 聚合根在不同的机器上在被一同在做不同的修改,而是产生的事件的版本号是相同的,从而就会导致 并发修改同一俩个 聚合根的情况汇报了。

而是一俩个 妙招时会 实现并发冲突的检测: