京东服务市场高并发下SOA服务化演进架构(2)
系统使用一段时间后,由于业务系统对服务数据需求的不一致,服务开发人员开始为每个外部系统提供一块主动缓存。这些缓存完全不具备通用性但又数量众多。每次服务模型修改,研发人员都要花大量时间去维护这些不通用的缓存。占用的缓存越来越多,但缓存的使用率并不高。 为去除冗余,降低维护工作量,最初按照数据表的维度将每一个表作为一个缓存。作为ES缓存可以采用这个方案,但是对于Redis缓存,这种缓存方式却带来了很大的麻烦。 数据库表设计为保证强一致性,建表的时候严格依照范式,数据中很少有冗余,表也切的很小,查询时通过联合查询来获取整体数据。但Redis没有联合查询的功能,因此不得不多次调用不同的缓存,多次调用大大降低了性能。对于查询而言,数据库会进行一些反范式操作。既然Reids缓存能够支撑查询,那么也可以做一定的冗余把这些关联数据作为一个整体对象缓存起来。 对于服务开发人员而言,主要职责是根据环境变化,不断的进化服务模型。服务开发人员维护一套最新、最完整的服务模型并将模型开放出来;服务调用者,特别是只获取服务数据的调用者完全可以通过对服务完整模型的自定义裁剪获取自己所需要的数据,各开发人员只关注自己需要关注的地方,大大提高了工作效率。 3. 缓存构建方案 面临问题:
解决方案:
初期采取直接解析binlog报文,按照消息内容更新数据。为保证消费顺序性,必须只有一个队列进行消息传递,大大降低了效率,并埋下了单点的隐患。 解决方法是,MQ不作为数据变化的承载者,而是作为一个通知者。当缓存构造者接受到MQ的时候,从数据库获取最新的服务属性,更新到缓存中。通过拉式获取完整的服务属性数据,保证了数据的完整性、一致性。而主动拉取数据,不限制于消息本身,也不需要保证消息顺序性,完美解决效率与单点问题。在属性被多次修改时,更能在其他修改消息未接收到时,就已经拉取到最新数据更新了缓存数据,进一步提高了实时性。 最后,单向事件触发有很小的概率还是会发生数据不一致。解决办法是,采用定时比对的方式,每个小时(可调整)通过时间戳比对当日数据与缓存数据差异,进行最终补偿。 四、后记 解决了不同服务对相同资源的调用冲突,服务内不同的场景使用不同的资源支撑,创建了统一缓存层摆脱对数据库的依赖。使用不同的方法解决了当统一缓存建立以后,如何使查询摆脱了对数据库的强依赖,服务性能得到了非常大的提升。 改造前支撑调用量: 改造后支撑调用量: 通过以上演进,“可用插件列表服务”并发性能有了很大的提升。 2018年11.11零点调用量10分钟内陡增6倍,平稳度过。 作者简介:研发老兵,热爱技术,喜欢挑战。熟悉各种开源框架,对大型分布式系统有丰富的架构、设计经验。性能卓越、设计优雅是其一生的追求。 【本文来自51CTO专栏作者张开涛的微信公众号(开涛的博客),公众号id: kaitao-1234567】 戳这里,看该作者更多好文 (编辑:ASP站长网) |