当前位置:首页 > 问答 > 正文

Kafka和数据库怎么搭配用,数据传输那事儿其实没那么难解决

关于Kafka和数据库怎么搭配用,数据传输那事儿其实没那么难解决,这个问题的核心在于理解它们各自的特长,然后让它们像两个好搭档一样分工合作,你别把它们看成是互相替代的关系,而应该看成是接力赛跑的队友,数据库,尤其是像MySQL、PostgreSQL这类关系型数据库,它的强项是“保管”,就是最终把数据整整齐齐、安安稳稳地存好,保证数据不出错、不丢失,适合用来做复杂的查询,而Kafka的强项是“搬运”,它像一个超级高效、永不堵车的传送带,专门处理海量数据的实时流动。

(来源:基于Kafka官方对其作为分布式事件流平台的定位,以及传统数据库ACID特性的普遍认知)

那它们具体怎么搭配呢?最常见、也最经典的用法就是“数据库变更抓取”,我举个简单的例子你就明白了,想象一下一个电商网站,每当用户下了一个新订单,这个订单信息肯定会先被写入到后端的订单数据库里存起来,这是最基本的操作,但现在,这个“下订单”这个动作背后,可能牵涉到很多事情要立刻去做:比如库存系统需要扣减库存,营销系统要计算积分,推荐系统要根据新订单更新推荐商品列表,财务系统可能要开始准备开发票。

(来源:业界常见的微服务架构下数据同步场景)

如果没有Kafka,传统做法可能是这些系统都直接去频繁地查询订单数据库,看有没有新订单,但这会带来好几个头疼的问题:第一,订单数据库压力会非常大,因为它本来专心存数据就好,现在还要被一大堆查询骚扰;第二,如果库存系统临时出故障了,它可能就错过了某段时间的新订单,导致数据不一致;第三,各个系统耦合得太紧,一旦订单数据库的表结构要改动,所有相关系统可能都得跟着改,非常麻烦。

(来源:描述直接数据库查询集成模式带来的耦合、性能瓶颈和单点故障风险)

这时候,Kafka的价值就体现出来了,我们可以用一个叫CDC的工具(比如Debezium),这个工具就像安在数据库日志上的一个“监视器”,它不打扰数据库的正常工作,只是实时地监控数据库的日志文件(数据库自己记录的每一个数据变更的流水账),一旦发现有新订单插入,CDC工具立刻把这个“新增了一条订单记录”这个事件,连同订单的详细信息,作为一个消息,快速地扔到Kafka这个传送带上。

(来源:Debezium等项目的工作原理是捕获数据库变更日志)

接下来就优雅多了,库存系统、营销系统、推荐系统等等,它们不再是直接去骚扰数据库了,而是各自派一个“小工”(消费者)守在Kafka传送带旁边,专门领取属于自己的那种消息,库存系统的小工只关心订单消息,领到后就去扣库存;营销系统的小工也领同样的消息,但它是去处理积分,这样一来,好处非常明显:

  1. 数据库减压了:它只需要安心接待写数据的请求(下单),不用再应付海量的查询,性能更稳定。
  2. 解耦了:各个系统只跟Kafka打交道,彼此不认识也没关系,哪怕库存系统宕机一小时,没关系,它恢复后可以继续从Kafka那里领取停机期间错过的所有订单消息,不会丢数据,这就是Kafka消息持久化的能力。
  3. 扩展性好:如果突然搞促销,订单量暴增,只需要增加处理消息的“小工”数量就行,Kafka这个传送带能扛住很大的流量。
  4. 实时性高:数据几乎是在写入数据库的同时就被传递出去了,其他系统能近乎实时地做出反应。

(来源:总结Kafka在异步解耦、削峰填谷、保证数据最终一致性方面的优势)

除了这种主流的用法,还有一种反过来用的场景,叫“物化视图”,我们需要的数据并不是直接存在数据库里的原始样子,可能是多个表连接计算后的结果,如果每次都让数据库现场计算,对数据库负担很重,这时候,我们可以让各个相关表的数据变更,都通过CDC工具流到Kafka里,用一个流处理程序(比如Kafka Streams或者Flink)实时地在Kafka的流上把这些数据关联、计算好,最后把计算好的结果再写回到另一个数据库(比如Elasticsearch用于搜索,或者另一个MySQL用于只读查询)里,这样,查询用的数据库只存放最终结果,查询速度飞快,而源数据库的压力也小了。

(来源:描述通过流处理构建物化视图以提升查询性能的架构模式)

你看,Kafka和数据库的搭配,精髓就在于“流水线”作业,数据库做它最擅长的“最终存储和精确查询”,扮演一个可靠的数据终点站;而Kafka则负责中间高速的“数据传输和分发”,扮演一个永不疲倦的搬运工,它们两个一静一动,一稳一快,结合起来就能很好地解决微服务架构下,数据如何可靠、高效、实时地流动这个老大难问题,你不需要强行用一个去完成另一个的工作,而是让它们协同,这样数据传输那事儿就真的没那么难解决了。

(来源:综合总结两者在数据架构中的互补定位与协同价值)

Kafka和数据库怎么搭配用,数据传输那事儿其实没那么难解决