Solr 9.9.0高负载下响应缓慢甚至崩溃问题求助
Solr 9.9.0高负载下响应缓慢/崩溃的解决方案
问题背景
使用Solr 9.9.0,服务器内存升级至32GB,JVM堆内存设为16GB;单Core存储30万条记录,供多搜索应用调用。高负载场景下Solr UI及应用响应缓慢甚至崩溃,已调整solrconfig.xml、solr.in.sh配置并停止主从复制,问题仍存在。当前物理内存使用率59.7%(18.57/31.09GB),JVM堆内存仅使用7.2%(1.15/16GB)。
排查与优化步骤
1. 系统资源瓶颈排查
- 磁盘IO检测:执行
iostat -x 1查看磁盘负载,若%util接近100%或await数值过高(超过50ms),说明磁盘IO是核心瓶颈,建议更换SSD或优化索引存储路径。 - CPU使用率监控:用
htop观察Solr进程CPU占用,若持续满负载,需优化查询语句或索引字段(如减少分词复杂度)。 - 文件句柄调整:CentOS9默认文件句柄数不足,编辑
/etc/security/limits.conf添加:
重启Solr生效,避免因句柄耗尽导致崩溃。solr soft nofile 65535 solr hard nofile 65535 - 网络带宽检查:若应用与Solr跨服务器部署,用
iftop确认带宽是否占满,排查网络丢包问题。
2. JVM参数优化(针对低堆使用率的异常)
堆内存仅用1.15G说明堆不是瓶颈,重点优化非堆内存与GC行为:
- 添加GC日志排查停顿:在
solr.in.sh的SOLR_OPTS中追加:
若日志中出现超过500ms的GC停顿,调整G1GC参数:降低-Xlog:gc*:file=/var/log/solr/gc.log:time,level,tags:filecount=10,filesize=100mMaxGCPauseMillis至100,或设置-XX:InitiatingHeapOccupancyPercent=60减少GC触发频率。 - 关闭大页支持(若未配置):注释
GC_TUNE中的-XX:+UseLargePages,系统未配置大页时该参数会导致内存分配异常。 - 显式设置堆外内存:Solr依赖堆外Direct Memory,添加到
SOLR_OPTS:
避免堆外内存不足引发的崩溃。-XX:MaxDirectMemorySize=8g
3. Solr缓存与索引配置优化
结合30万条数据的场景,调整缓存策略:
- 替换filterCache为CaffeineCache:Caffeine比FastLRU更高效,修改
solrconfig.xml:<cache name="filterCache" class="solr.CaffeineCache" size="8192" initialSize="2048" autowarmCount="1024"/> - 优化queryResultCache命中率:开启缓存统计,调整size:
通过Solr UI的Core Admin查看缓存命中率,若低于50%,将size降至2048或直接关闭(size=0)。<cache name="queryResultCache" class="solr.LRUCache" size="4096" initialSize="512" autowarmCount="512" stats="true"/> - 扩容documentCache:提升文档缓存容量,减少磁盘读取:
<cache name="documentCache" class="solr.CaffeineCache" size="4096" initialSize="1024" autowarmCount="512"/> - 调整ramBufferSizeMB:提升至512M优化索引加载效率:
<ramBufferSizeMB>512</ramBufferSizeMB> - 延长autoSoftCommit时间:若无需实时数据,将
maxTime从15000ms改为30000ms,减少软提交开销。
4. 查询与索引结构优化
- 开启慢查询日志:在
solrconfig.xml中添加:
针对慢查询优化:避免通配符开头的查询(如<requestDispatcher handleSelect="true"> <queryLog enable="true" threshold="500"/> <!-- 记录超过500ms的查询 --> </requestDispatcher>*keyword),用fl指定返回字段,优先使用fq过滤查询(可被filterCache缓存)。 - 优化字段属性:对过滤、排序字段设置
docValues="true",禁用非必要字段的indexed属性,减少索引体积。
5. 线程池与连接数控制
- 调整查询线程池:在
solrconfig.xml中修改queryThreadPool:
适配多应用并发请求。<queryThreadPool size="10" maxSize="200" coreSize="10"/> - 限制客户端连接数:每个搜索应用的HTTP连接池最大连接数设为20-30,总连接数不超过Solr线程池最大数,避免线程耗尽。
6. 监控验证
- 通过Solr UI的Core Admin -> Statistics监控缓存命中率、QPS、平均查询时间。
- 用
jstat -gc <solr_pid> 1000实时监控GC状态,排查频繁GC或内存泄漏。 - 用
jstack <solr_pid>查看线程状态,定位锁竞争或资源阻塞问题。
内容的提问来源于stack exchange,提问作者Abhishek




