面试题答案
一键面试合理分片策略
- 按商品ID分片:
- 原理:以商品ID作为分片键,通过哈希函数将商品ID映射到不同的Redis节点。例如使用CRC16哈希算法对商品ID进行计算,然后对Redis节点数量取模,决定数据存储在哪个节点。
- 优势:适合商品信息的缓存,同一商品的所有相关操作(如查询商品详情、库存等)都能定位到同一节点,提高缓存命中率,减少跨节点查询开销。在高并发读取商品信息时,能有效分散负载。
- 应用场景:商品详情页展示、商品库存查询等频繁读取商品数据的场景。
- 按用户ID分片:
- 原理:以用户ID作为分片键,同样通过哈希函数映射到Redis节点。
- 优势:对于用户购物车和订单数据,同一用户的所有购物车和订单相关操作都集中在一个节点,方便管理和维护用户状态。比如用户添加商品到购物车、修改购物车商品数量、下单等操作,都能在一个节点完成,保证数据一致性,也利于在高并发下处理用户的个性化操作。
- 应用场景:购物车操作、订单创建与查询等与用户紧密相关的业务场景。
- 复合分片:
- 原理:结合商品ID和用户ID等多个维度进行分片。例如先根据用户ID进行粗粒度分片,在每个用户对应的节点内,再根据商品ID进行细粒度分片。
- 优势:综合了按商品ID和按用户ID分片的优点,在处理一些涉及用户与商品交互的复杂业务时更灵活,如用户查看自己购物车中某商品的优惠信息,既能快速定位到用户相关节点,又能在该节点内找到具体商品数据,进一步提高缓存命中率和并发处理能力。
- 应用场景:复杂的电商业务逻辑,如购物车内商品的个性化促销活动计算等。
可能遇到的问题及解决方案
- 数据倾斜:
- 问题描述:某些节点存储的数据量和负载远高于其他节点,导致部分节点压力过大,影响整体性能。例如热门商品ID经过哈希后集中到少数几个节点,使得这些节点成为瓶颈。
- 解决方案:
- 虚拟节点:引入虚拟节点概念,每个物理节点对应多个虚拟节点。在计算分片时,先将数据映射到虚拟节点,再由虚拟节点映射到物理节点。这样能更均匀地分配数据,减少数据倾斜。
- 动态调整:定期监控节点负载情况,当发现某个节点负载过高时,动态将部分数据迁移到负载较低的节点。Redis Cluster本身支持节点间的数据迁移,但需要合理设置迁移策略和阈值。
- 缓存穿透:
- 问题描述:查询一个不存在的数据,每次都穿透缓存到数据库查询,增加数据库压力。比如恶意用户频繁查询不存在的商品ID。
- 解决方案:
- 布隆过滤器:在缓存之前使用布隆过滤器,将所有可能存在的键值对提前存储在布隆过滤器中。查询时先通过布隆过滤器判断,如果不存在则直接返回,不查询数据库。虽然布隆过滤器可能存在误判,但能有效减少大部分无效查询。
- 空值缓存:当查询结果为空时,也将空值缓存起来,并设置较短的过期时间,下次查询相同数据时直接从缓存获取空值,避免查询数据库。
- 缓存雪崩:
- 问题描述:大量缓存数据在同一时间过期,导致大量请求直接打到数据库,造成数据库压力过大甚至崩溃。
- 解决方案:
- 随机过期时间:设置缓存过期时间时,在一个合理范围内设置随机值。例如原本设置缓存过期时间为1小时,可以改为在50分钟到70分钟之间随机取值,避免大量缓存同时过期。
- 二级缓存:采用二级缓存架构,一级缓存失效后,先从二级缓存获取数据。二级缓存可以采用不同的过期策略或存储介质,如使用本地缓存(如Guava Cache)作为二级缓存,减轻数据库压力。
- 网络分区:
- 问题描述:由于网络故障等原因,Redis Cluster被分割成多个独立的子网,不同子网内的节点无法通信,导致数据不一致和部分节点不可用。
- 解决方案:
- 配置合适的参数:合理设置Redis Cluster的节点超时时间(cluster-node-timeout)等参数,当节点在规定时间内无法通信时,集群能够自动进行故障检测和转移。
- 多副本和自动故障转移:Redis Cluster本身支持每个主节点有多个从节点,当主节点出现故障(如因网络分区导致不可达)时,从节点能够自动晋升为主节点,保证服务的可用性。同时,需要监控集群状态,及时处理网络恢复后的集群合并问题,确保数据一致性。