什么是服务端缓存:
服务端缓存是将数据或计算结果缓存在服务器内存中,以便更快地响应客户端请求。当客户端发送请求时,服务器首先检查缓存以查找已经计算好的结果,如果找到了相应的结果,则可以直接返回给客户端,从而避免了重新计算和查询数据库等操作,提高了系统性能和响应速度。常见的服务端缓存技术包括内存缓存、分布式缓存等。
缓存实现:
名称 | 优点 | 缺点 |
内存 | - 访问速度快:内存读写速度比磁盘等其他媒介要快得多。
- 响应时间短:由于数据已经被缓存在内存中,因此可以直接从内存中获取而不需要重新计算或查询数据库等操作,从而减少了响应时间。
- 易于实现和管理:内存缓存的实现相对简单,管理也比较容易。
- 可扩展性好:可以通过增加服务器内存的方式来提高整个系统的性能。
| - 数据存在丢失风险:当服务器重启或崩溃时,内存中缓存的数据会丢失,因此不能永久保存数据。
- 有限的存储空间:内存缓存通常只能存储有限的数据,如果需要缓存大量数据,则需要使用分布式缓存等其他技术。
- 不适合大规模数据访问:内存缓存适用于小规模、频繁访问的数据,但对于大规模数据访问,可能会导致内存压力过大,影响系统稳定性。
|
redis | - 高性能:Redis 将数据保存在内存中,读写速度非常快。
- 数据类型丰富:Redis 支持多种数据类型,包括字符串、哈希表、列表、集合、有序集合等。
- 持久化支持:Redis 提供了两种持久化方式,可以将数据保存到磁盘中以防止数据丢失。
- 高可用性:Redis 支持主从复制和 Sentinel 等机制,保证了数据的可靠性和高可用性。
- 分布式支持:Redis 提供了分片技术,可以将数据分散在多个节点上,提高了系统的扩展性和容错性。
| - 内存限制:由于 Redis 将所有数据保存在内存中,因此需要考虑内存容量的限制。
- 不适合大型数据:对于大型数据的处理,Redis 可能无法胜任或者需要特殊配置。
- 数据不是永久存储:Redis 的持久化机制虽然可以将数据保存到磁盘中,但仍然无法保证数据的永久存储。
- 高可用性需要额外配置:如果需要实现高可用性,需要进行额外的配置和管理。
|
mongo | - 高可扩展性:MongoDB 具有良好的横向扩展能力,可以通过添加更多的节点来扩展集群。
- 灵活的数据模型:MongoDB 支持动态数据模型,可以存储不同结构的数据类型,适用于灵活和快速变化的业务场景。
- 内置复制和故障转移功能:MongoDB 支持内部自动故障转移和自动恢复功能,从而实现高可用性。
- 高性能:MongoDB 的读写性能非常高,支持高并发读写操作。
- 丰富的查询语言:MongoDB 支持强大的查询语法和索引机制,方便用户进行复杂的查询。
| - 不支持事务:MongoDB 不支持复杂的事务操作,只支持单文档事务。
- 使用存储空间较大:由于 MongoDB 存储了许多元数据信息,因此使用的存储空间比其他数据库要大一些。
- 配置和管理相对复杂:MongoDB 的配置和管理相对复杂,需要花费更多时间和精力。
|
memcached | - 高性能:Memcached 将数据保存在内存中,读写速度非常快,适用于需要高速读写的场景。
- 简单易用:Memcached 的实现相对简单,可以轻松部署和管理。
- 分布式支持:Memcached 支持分布式缓存,可以将数据分散在多个节点上,提高了系统的扩展性和容错性。
- 可扩展性好:可以通过增加服务器内存或添加新的节点来提高整个系统的性能。
| - 仅支持键值对存储:Memcached 仅支持简单的键值对存储,不支持复杂的数据类型和查询操作,因此适用于无需复杂操作的场景。
- 数据不是永久存储:Memcached 将所有数据保存在内存中,如果服务器重启或崩溃,则所有数据都会丢失。
- 安全性较低:Memcached 不提供任何安全保护措施,如访问控制、认证等,因此需要特别注意数据的安全问题。
|
缓存穿透
名称 | 解释 |
缓存穿透 | 指的是恶意攻击或者系统故障导致一些不存在的或者不合法的 key 被频繁请求,从而直接访问数据库,导致数据库压力巨大,甚至崩溃。这种情况通常发生在缓存层无法识别非法请求,导致无效的请求直接访问数据库。 |
缓存击穿 | 指的是在高并发场景下,某个 key 频繁失效或者被删除,导致大量请求直接访问数据库,从而造成数据库压力过大,甚至宕机。这种情况通常发生在缓存中没有相应的数据,但又有大量的请求同时访问该数据,导致每次都要查询数据库。 |
缓存雪崩 | 指的是在缓存中多个 key 在同一时间内失效,导致大量请求直接访问数据库,造成数据库压力过大,甚至宕机。这种情况通常发生在缓存中的数据具有相同的过期时间,当缓存中的数据全部失效时,会导致大量请求一起访问数据库。 |
研发如何设计缓存:
- 缓存选择:根据实际业务场景,合理选择适合的缓存技术,比如内存缓存、分布式缓存(比如 Redis、Memcached 等)等。
- 缓存清除策略:定期或根据业务需要清理过期或无效的缓存,避免缓存占用过多内存或导致问题。
- 缓存更新策略:当数据被修改时,需要及时更新相应的缓存,保证缓存数据的一致性。
- 缓存预热策略:在系统启动时或者高峰期之前,提前加载常用数据到缓存中,避免由于冷启动或大量请求造成的压力过大。
- 缓存穿透解决方案:使用布隆过滤器或者添加互斥锁,防止缓存穿透问题。
- 数据库与缓存同步策略:当数据被更新或删除时,需要及时将相应的缓存清除或更新,保证数据的一致性。
- 可视化监控和日志记录:通过可视化监控和日志记录,实时了解缓存系统运行状态,发现潜在问题并及时处理。
CA研发的缓存策略:禁止穿透到db,缓存插件实现预热等相关逻辑
同步咨询师列表缓存-无过期时间-限制缓存穿透
获取咨询师详情-设置缓存时间-定向穿透失败读缓存-兜底
下面的代码展示了混合缓存的使用
混合redis+内存保存咨询师详情数据
缓存如何测试:
数据正确性:
- 序列化,反序列化测试,只管感受是api报错或者返回数据乱码
- 数据是否满足当前条件
- 如果服务没有动态数据返回(固定参数返回值),多次请求数据是否一致
- 如果服务有动态数据,请求返回是否满足逻辑
缓存时效及加载
- 缓存是否设置过期时间
- 缓存过期了是否立即刷新缓存
- 缓存是否会在过期前一端时间预热加载新缓存
- 删除缓存后请求,缓存是否会自动更新
大key
- key命名是否太大
- key对应value只是否太大 string list obj等 导致连接池被占用,阻塞其他请求,大数据量会占用更多cpu处理,导致响应慢,影响redis,及服务的性能
安全性
- 缓存策略是否满足阻止其他应用入侵内存修改等操作
- 使用的中间件是否无加密直接访问
性能
多层缓存测试
- 同上,要注意缓存兜底策略,谁是谁的兜底,数据对象是否要一致等