Cassandra作为事件存储的最佳选择之一

Cassandra特点是写入快,而在一个事件驱动架构EDA或Event sourcing中,我们需要一个可伸缩扩展的数据库来保存快速发生且不断增长的事件日志,将系统正在发生所有事件都进行保存,然后在适当时候进行事件回放,或者需要时进行数据挖掘分析。

这其中涉及多个重要技术环节:
首先如何第一时间把用户操作事件截取下来,这可以参考LMAX架构,使用disruptor对事件进行分发,也可以使用JdonFramework的事件元注释通过DCI对用户的输入事件进行异步快速分发。

其次,是否直接分发到Cassandra?简单系统可以,但是复杂系统最好分发到一个消息中心,然后由消息中心分发保存到Cassandra,这样弹性可扩展性更好 。这个消息系统可以使用ActiveMQ等通用,也可以使用开源Apache Kafka,值得注意的是,Event Sourcing和ESB事件总线SOA两种架构对消息系统要求不同,前者要求高性能高吞吐量;后者要求高灵活性高可配置型,灵活性环节增多,意味响应延迟性可能增加。

各个渠道的操作事件汇聚保存快速写入到Cassandra后,如果需要事件日志回滚,比如查询某段时间内的事件,就涉及到Cassandra操作了,Cassandra: Lessons Learned | Javalobby一文谈到了这方面细节:

这是一个SOA架构WSO2中采取Cassandra作为业务活动监视Business Activity Monitoring,其实就是一种类似ES架构。

Cassandra记录事件日志数据格式是:
Event Id | Server:esb12 | time:08:00
Cassandra:作为事件存储的最佳选择
这段格式记录的是每台ESB服务器如esb12的处理事件的时间,如8点。

这是esb12事件发生写入Cassandra的原始日志格式,如果我们需要事件回滚,查询服务器esb12在08:00和09:00之间发生的事件,直接从这个原始格式查询性能是慢的,该文介绍了如何在原始日志格式上建立一种索引,以便进行复杂查询的方法。


[该贴被banq于2011-12-07 14:33修改过]


Cassandra的数据结构是一种类似Json格式的列表:
KeyA ColumnA ColumnB ColumnC
其中ColumnA是一种属性值,属性名/属性值 name/value这种值对。

按照上面这张图,建立一种查询某个服务器在某段时间发生的事件的索引步骤如下:
1. 首先从原始日志记录中读取出事件数据

2. 如果事件包含服务器名和发生时间,那么创建一个新的数据Key,以服务器和发生时间为Key,如server是esb12,时间是8:00,那么新的key是esb12--8:00

3. 将这个新的Key数据创建到Cassandra中,新数据的值是事件ID。

4. 将这个新的数据作为一个列创建在indexRow列表中。这个indexRow列表的数据是类似esb11--6:00 ... esb12--8:00 esb12--10:00 ...数值。

当需要查询某段时间内某个服务器发生的事件,实际首先查这个indexRow,得到符合范围的数据值,而数据值是Event ID,再根据ID到原始事件日志中获得数据集结果。