使用Redis作为缓存优化ElasticSearch读写性能_redis存储es结果
在现代数据密集型应用中,ElasticSearch凭借其强大的全文搜索能力成为许多系统的首选搜索引擎。然而,随着数据量和查询量的增长,ElasticSearch的读写性能可能会成为瓶颈。本文将详细介绍如何使用Redis作为缓存层来显著提升ElasticSearch的读写性能,包括完整的架构设计、详细实现、Python代码示例和性能测试结果。
1. 架构设计
1.1 核心架构图
#mermaid-svg-VjPa60kKLsW9lAmp {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-VjPa60kKLsW9lAmp .error-icon{fill:#552222;}#mermaid-svg-VjPa60kKLsW9lAmp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VjPa60kKLsW9lAmp .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-VjPa60kKLsW9lAmp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VjPa60kKLsW9lAmp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VjPa60kKLsW9lAmp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VjPa60kKLsW9lAmp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VjPa60kKLsW9lAmp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VjPa60kKLsW9lAmp .marker.cross{stroke:#333333;}#mermaid-svg-VjPa60kKLsW9lAmp svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VjPa60kKLsW9lAmp .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VjPa60kKLsW9lAmp .cluster-label text{fill:#333;}#mermaid-svg-VjPa60kKLsW9lAmp .cluster-label span{color:#333;}#mermaid-svg-VjPa60kKLsW9lAmp .label text,#mermaid-svg-VjPa60kKLsW9lAmp span{fill:#333;color:#333;}#mermaid-svg-VjPa60kKLsW9lAmp .node rect,#mermaid-svg-VjPa60kKLsW9lAmp .node circle,#mermaid-svg-VjPa60kKLsW9lAmp .node ellipse,#mermaid-svg-VjPa60kKLsW9lAmp .node polygon,#mermaid-svg-VjPa60kKLsW9lAmp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VjPa60kKLsW9lAmp .node .label{text-align:center;}#mermaid-svg-VjPa60kKLsW9lAmp .node.clickable{cursor:pointer;}#mermaid-svg-VjPa60kKLsW9lAmp .arrowheadPath{fill:#333333;}#mermaid-svg-VjPa60kKLsW9lAmp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VjPa60kKLsW9lAmp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VjPa60kKLsW9lAmp .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-VjPa60kKLsW9lAmp .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-VjPa60kKLsW9lAmp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VjPa60kKLsW9lAmp .cluster text{fill:#333;}#mermaid-svg-VjPa60kKLsW9lAmp .cluster span{color:#333;}#mermaid-svg-VjPa60kKLsW9lAmp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VjPa60kKLsW9lAmp :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} Read Write Hit Miss Client Request Type Redis Cache Elasticsearch Return Data Query Elasticsearch Cache Result to Redis Invalidate Cache
1.2 核心流程说明
-
读请求处理流程:
- 客户端发起读请求
- 系统首先查询Redis缓存
- 如果缓存命中,直接返回缓存数据
- 如果缓存未命中,查询ElasticSearch获取数据
- 将查询结果存入Redis缓存并设置过期时间
- 返回数据给客户端
-
写请求处理流程:
- 客户端发起写请求(创建、更新或删除文档)
- 系统直接写入ElasticSearch
- 删除与该文档相关的Redis缓存(缓存失效)
- 返回操作结果给客户端
-
缓存策略:
- 高频文档:使用Redis String存储单个文档
- 聚合结果:使用Redis Hash存储固定条件的聚合结果
- 过滤查询:使用Redis String存储预计算的过滤查询结果
- 过期策略:设置TTL(5-30分钟)实现自动过期,平衡数据新鲜度和缓存命中率
2. 详细设计
2.1 缓存场景分析
根据业务需求,我们确定了三种主要的缓存场景:
-
高频单文档查询:
- 场景:通过ID快速获取单个文档(如商品详情、用户信息)
- 特点:访问频率高,数据量小,对延迟敏感
- 缓存策略:使用Redis String存储,设置较短的TTL(如300秒)
-
固定条件聚合结果:
- 场景:如近期热销商品统计、用户行为分析
- 特点:计算成本高,结果相对稳定,访问频率中等
- 缓存策略:使用Redis Hash存储,设置中等TTL(如600秒)
-
静态过滤条件结果:
- 场景:如预计算的分类列表、标签云
- 特点:数据变化不频繁,访问频率高
- 缓存策略:使用Redis String存储,设置较长的TTL(如1800秒)
2.2 缓存键设计
合理的缓存键设计对于高效缓存至关重要:
es:doc:{index}:{id}
{index}
为索引名,{id}
为文档IDes:agg:{index}:{query_hash}
{query_hash}
为查询条件的MD5哈希值es:query:{index}:{filter}
{filter}
为过滤条件的字符串表示