为简单起见,把数据分成两大类,一类是关键的交易性数据,以存储在关系型数据库为主,另一类是日志型数据,以存储在日志型消息队列(如kafka)为主。第二类数据,消费端到感知到最新的变化数据,采用内嵌的pull机制,比较容易实现,同时日志类数据,绝大部分是Append-only,不涉及到删改,无论是采用ClickHouse还是使用TimeScaleDB都可以达到很好的实时聚合效果,这里就不再赘述。针对第一类存储在数据库中的数据,要想实时感知到变化的数据(这里的变化包含有增/删/改三种操作类型),有两种打法。打法一:基于时间戳方式的数据同步,假设在表设计时,每张表中都有datachange_lasttime字段表示最近一次操作发生的时间,同步程序会定期扫描目标表,把datachange_lasttime不小于上次同步时间的数据拉出进行同步。这种处理方式的主要缺点是无法感知到数据删除操作,为了规避这个不足,可以采用逻辑删除的表设计方式。数据删除并不是采取物理删除,只是修改表示数据已经删除的列中的值标记为删除或无效。使用这种方法虽然让同步程序可以感知到删除操作,但额外的成本是让应用程序在删除和查询时,操作语句和逻辑都变得复杂,降低了数据库的可维护性。打法一的变种是基于触发器方式,把变化过的数据推送给同步程序。这种方式的成本,一方面是需要设计实现触发器,另一方面是了降低了insert/update/delete操作的性能, 提升了时延,降低了吞吐量。打法二:基于CDC(Change Data Capture)的方式进行增量数据同步,这种方式对数据库设计的侵入性最小,性能影响也最低,同时可以获得丰富的开源组件支持,如Cannal对MySQL有很好支持,Debezium对PostgreSQL有支持。利用这些同步组件,把变化数据写入到Kafka,然后供后续实时数据分析进一步处理。