# 《分布式IM系统》通用模型-第02节:分布式IM即时通讯系统通用缓存设计

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)
课程视频:https://t.zsxq.com/15GZ04X9k (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★☆☆☆
  • 本章重点:对分布式IM即时通讯系统的通用缓存进行设计和实现,使其具备高度可扩展性。重点掌握面向接口编程的核心思想,掌握扩展性代码的落地实现方案,并能够将其灵活应用到自身实际项目中。
  • 课程视频:https://t.zsxq.com/15GZ04X9k (opens new window)

大家好,我是冰河~~

可以这么说,绝大部分互联网项目都会使用到缓存,使用缓存不仅仅可以提升系统的读性能,还能在高并发大流量场景下保护数据库不被流量打垮,并且分布式缓存也可以实现各个微服务之间共享数据状态。另外,大部分高并发、大流量的互联网项目都会采用本地缓存+分布式缓存的混合型缓存设计。

# 一、前言

像分布式IM即时通讯系统这种高并发、大流量的项目,毋庸置疑,都是需要设计缓存的。在分布式IM即时通讯系统中,缓存不仅仅用来缓存读热点数据,提升系统的读性能,保证数据库的稳定性和安全性,也不只是实现各个微服务之间共享数据的状态,在分布式IM即时通讯系统中,缓存还会有更加重要的应用场景。

# 二、本节诉求

对分布式IM即时通讯系统设计通用的本地缓存+分布式缓存的混合型缓存,并落地到代码实现,同时,需要实现缓存代码的高度可扩展性,方便系统后期的随时扩展,掌握面向接口编程的核心思想,并能够将其灵活应用到自身实际项目中。

# 三、应用场景

在分布式IM即时通讯系统中,缓存除了能起到常规作用外,更重要的是,在分布式IM即时通讯系统中,缓存还要支持这些场景:存储与用户终端建立连接的IM即时通讯服务ID,用户的在线状态、用户已读的单聊以及群聊消息的最大ID,视频会话信息等等内容。

所以,总体来说,在分布式IM即时通讯系统中,缓存的使用场景包含但不限于图2-1所示。


# 四、混合型缓存设计

总体来说,在缓存设计的过程中,会采用本地缓存+分布式缓存的混合型缓存设计方案。其中,本地缓存指的就是单机缓存,比如JVM内存缓存,单机Cache缓存。分布式缓存指的是以分布式的方式集中管理的缓存,比如Memcached、Redis等,并且在设计本地缓存+分布式缓存的混合型缓存方案时,要充分考虑到缓存穿透、击穿和雪崩问题。

# 4.1 扩展性设计

在分布式IM即时通讯系统中,本地缓存和分布式缓存相结合,能够抗住进入分布式IM即时通讯系统内部的大部分流量。并且在技术选型上,本地缓存默认基于Guava Cache实现,分布式缓存则默认基于Redis实现。并且本地缓存不仅仅只是支持Guava Cache,分布式缓存不仅仅只是支持Redis,在代码层面,都是面向接口编程,而非面向具体实现类编程,不管是本地缓存还是分布式缓存,都可以根据简单的配置切换具体的实现方式。

在代码设计上,代码具备良好的扩展性,后续维护和升级的成本就比较低。相反,如果代码写的杂乱无章,犹如“屎山”,那后期维护起来是相当痛苦的,谁也不想天天面对着一堆“屎山”,哪来有问题改哪里。所以,从一开始写的代码就要有良好的扩展性,方便后期的维护和升级。

分布式IM即时通讯系统整体是基于SpringBoot实现的,那如何写代码具备良好的扩展性呢?总体的原则就是面向接口编程,而非面向具体的实现类编程,具体业务逻辑里依赖的是接口,而非实现类,在接口不变的前提下,可以随时切换具体的实现类,也可以随时新增接口的实现类。业务中可以根据配置加载接口的某个具体实现类。

# 4.2 本地缓存设计

本地缓存的扩展设计示意图如图2-2所示。

# 查看完整文章

加入冰河技术 (opens new window) 知识星球,解锁完整技术文章、小册、视频与完整代码