常用的索引类型
- B-树索引:
- 适用于范围查询、等值查询和排序操作。
- 结构平衡,适合大多数的查找操作。
- B+树是B-树的一种常见变种,所有的值都在叶子节点上,叶子节点按顺序链接,方便范围查询。
- 哈希索引:
- 适用于等值查询。
- 通过哈希函数将键值映射到对应的存储位置,查询速度快。
- 不适用于范围查询,因为哈希函数无法保证键值的顺序。
- 全文索引:
- 适用于全文搜索,例如搜索包含某个词或短语的文档。
- 常用于文本数据的检索,如搜索引擎。
- 支持分词和多种语言。
- 空间索引:
- 适用于地理数据或多维数据的查询。
- 如R-树,用于地理信息系统(GIS)中的位置查询。
- 唯一索引:
- 强制列中的所有值唯一。
- 保证数据表中数据的唯一性,防止重复数据的插入。
- 组合索引:
- 包含多个列的索引。
- 提高多列组合查询的性能,特别是当查询条件中包含多个列时。
- 主键索引:
- 表的主键自动创建的索引。
- 唯一且非空,通常为B-树索引。
- 二级索引(辅助索引):
- 非主键列上创建的索引。
- 辅助查找非主键列的数据,提高查询性能。
这些索引类型在不同的场景下有不同的应用,通过选择合适的索引类型,可以显著提高数据库查询的效率。
缓存穿透、缓存击穿、缓存雪崩
缓存穿透、缓存击穿和缓存雪崩是分布式缓存系统中常见的问题,了解它们的成因和解决方案对于系统稳定性和性能优化至关重要。
缓存穿透
问题描述: 缓存穿透是指缓存和数据库中都没有的数据,每次请求都会直接穿透缓存,访问数据库,导致缓存失效,数据库压力增加。
成因: 通常由恶意请求或者程序错误引起,请求的数据根本不存在。
解决方案:
- 缓存空结果:对于查询不到的数据,缓存一个空结果(如空对象或特殊标识),设置较短的过期时间。
- 布隆过滤器:在请求缓存前,先通过布隆过滤器判断数据是否存在于数据库中,不存在则直接返回,减少对数据库的访问。
缓存击穿
问题描述: 缓存击穿是指某个热点数据在缓存中失效(过期)后,瞬间有大量请求直接访问数据库,造成数据库压力骤增。
成因: 热点数据的缓存失效,导致大量并发请求直接访问数据库。
解决方案:
- 互斥锁:使用分布式锁(如 Redis 分布式锁)保护缓存重建过程,只有一个线程可以访问数据库并重建缓存,其他线程等待。
- 提前重建缓存:设置缓存提前过期机制,在数据过期前主动刷新缓存。
- 随机过期时间:对缓存的过期时间增加随机因素,防止同一时间大量缓存同时失效。
缓存雪崩
问题描述: 缓存雪崩是指在某一时刻大量缓存同时失效,导致大量请求直接访问数据库,数据库压力剧增,甚至崩溃。
成因: 大量缓存同时设置相同的过期时间,导致同时失效。
解决方案:
- 缓存过期时间随机化:在设置缓存时,添加随机时间,避免同一时间大规模失效。
- 多级缓存:使用本地缓存和分布式缓存结合,减轻分布式缓存的压力。
- 缓存预热:在系统启动或重启时,提前加载热点数据到缓存中,避免初始阶段大量请求直接访问数据库。
- 限流降级:在缓存失效时,对数据库请求进行限流,确保数据库不会被压垮,同时对非关键请求进行降级处理。