随着umc接入主机的数量越来越多,每天产生的syslog日志数量也在剧增, 之前一天产生的syslog数量才不

到1W,随着整个集团的网络设备不端接入,导致现在每天产生的syslog数量大概在180w左右,而这些syslog对

网络和PE同学排查线上网络设备问题又是十分重要的,他们的要求是可以提供查询最近3个月的syslog, 保存一

年的syslog,在7月份的时候,针对量不多的情况,针对mysql单表做了索引,后来又做了单表备份,但是查询的

速度还是无法让人接受,后面又结合页面针对mysqlcount(*)语句做了优化: 使用count(*)语句只是在第一次查询

的时候查询一次,后面保存下来,在后面分页查询的时候,不再需要再查询总数量,即不调用count(*)之类的sql

语句,结果在翻页时,速度还是比较快,但首次查询的时候,还是非常非常慢,但这毕竟只是一个临时的解决方

案;后面结合syslog搜索的业务情况,结合各种技术参考,最终选择了使用Solr搜索引擎来解决syslog查找慢的

问题;

在做压力测试的时候,发现性能问题:在数据量不大(<1000W)的时候,用Solr搜索是比较快,但随着着

syslog数据量的不断增多,写索引和搜索的速度越来越不能让人接受,因此不得不考虑对Solr进行优化;

网上了搜了一下Solr优化的大体方案,主要从如下两个步骤来进行优化:

1.  Solr系统层面;

2.  索引字段优化;

针对Solr系统层的优化,主要有如下的方法:

1. 适当调大Solr查询缓存;

2.适当增加Solr集群的切片;

3根据查询的业务场景,适当调

整索引合并的时间,等等一系列通用的做法,针对这些修改以后,发现修改前后,对查询的性能没有本质

的提高;

针对索引字段的优化,就是针对添加到Lucence中文档各索引字段的优化, syslog索引字段主要的字段有:

id(Integer),

ip(String),

log_level(String),

log_value(String)

syslog_time(Date),

要针对这些字段优索引优化,就要首先分析索引查找的过程,要做到字段优化索引,可以从两方面考虑,

1. 减少字段索引存储量,

2. 提高查询索引比较的时间, 针对这两点,

可以毫不犹豫的考虑把String类型的字段向Integer或Long类型之类的整型字段映射转换(整型的索引存储空间

一般比字段串所占的存储索引空间要小;整型的查找比较速度比字段串类型要快,其实这也是数据库查找优化

的一个方面);基于这样的考虑,ip、log_level和syslog_time可以向相应的整型映射,各个字段具体的映射方

法如下:

1. ip 地址向整形映射,这个问题比较好解决,在计算机网络协议中,在底层是会把ip地址转换成对应的无

符号长整型,但由于java没有无符号这个概念,因此可以考虑把ip地址向整型或长整型做相互映射转换,但因为

整型比长整型占用的字节更少,因此采用整型,具体转换代码如下:

// 把ip地址转换成整形

  1. public static Long ipToInteger(String ip) {
  2. String[] ips = StringUtils.split(ip,'.');
  3. if (ips == null || ips.length < 4){
  4. throw newRuntimeException("ip地址非法!");
  5. }
  6. Integer integerIP = 0;
  7. Integer ip0= Integer.parseInteger(ips[0]);
  8. Integer ip1= Integer.parseInteger(ips[1]);
  9. Integer ip2= Integer.parseInteger(ips[2]);
  10. Integer ip3= Integer.parseInteger(ips[3]);
  11. if (ip0 > 255) {
  12. throw newRuntimeException("ip0地址非法:" + ip0);
  13. }
  14. if (ip1 > 255) {
  15. throw newRuntimeException("ip1地址非法:" + ip1);
  16. }
  17. if (ip2 > 255) {
  18. throw newRuntimeException("ip2地址非法:" + ip2);
  19. }
  20. if (ip3 > 255) {
  21. throw newRuntimeException("ip3地址非法:" + ip3);
  22. }
  23. integerIP |=( ip0 << 24) & (0xff000000);
  24. integerIP |=( ip1 << 16) & (0x00ff0000);
  25. integerIP |=( ip2 << 8) & (0x0000ff00);
  26. integerIP |=( ip3 << 0) & (0x000000ff);
  27. return integerIP ;
  28. }
  1. /**
  2. * int类型到ip转换
  3. * @param integerIP
  4. * @return
  5. */
  6. public static String integerToIP(IntegerintegerIP) {
  7. String ip = "";
  8. Integer ip0= (integerIP & 0xff000000) >>> 24;
  9. Integer ip1= (integerIP & 0x00ff0000) >> 16 ;
  10. Integer ip2= (integerIP & 0x0000ff00) >> 8;
  11. Integer ip3= (integerIP & 0x000000ff) >> 0;
  12. ip = ip0 + "." + ip1 +"." + ip2 + "." + ip3;
  13. return ip;
  14. }

2. log_level 只有8种值,分别是:Emergency, Alert, Critical, Error, Warning,Notice,Informational,

Debug; 这个好转换,直接按下表的方式做相互映射即可

Emergency

0

Alert

1

Critical

2

Error

3

Warning

4

Notice

5

Informational

6

Debug

7

3. 把syslog_time转换成Long类型,这个更容易,java中Date类型有一个getTime()方法

经过把这三个字段都转换成整型以后,索引插入和搜索速度都提高不少,特别是搜索速度有非常非常明显

的提升,特别是在数据量超过2亿的时间,效果更明显到此,字段优化完毕;

但此时还发现一个问题:一次查找返回的数据量太多,导致存在翻页慢的问题,例如:一次返回10W页数

据,如果一下翻到第10W页,查询的速度会非常非常慢甚至可能出现Solr集群全部宕机的情况,这是不能接受的,

因为我们页面上提供了翻到最后一面的功能, 虽然用户一般情况下不会这么做,但万一不小点错了,整个线上

Sorl集群就全部挂了,怎么办?这个问题,让我想起了mysql里的翻页的问题,下面两条SQL语句:

  • select * from umc_syslog where syslog_time between date1 and date2  order by id limit 0, 10;
  • select * from umc_syslog where syslog_time between date1 and date2  order by id limit 10000, 10;

我们知道,第一条SQL语句查询的速度非常快,第二SQL语句查询的速度非常慢,在系统压力较大的情况下,

可能会把mysql服务弄挂,根本原因在于limitstart, rows语句,mysql会在扫描时,会扫过满足结果的前start行的

记录,然后才读取len行的数据,如果start特别大,会非常慢,在高性能mysql这本书中介绍了各种解决分页问

题的优化,如延迟关联、阶递分页等,其中阶递分页可以在Solr中实现,但我们页面不允许这么做,不然早就

用Hbase来解决了,怎么办,在无解决的情况下,突然发现,Solr查询中有order by排序的问题,适当用order by

可以很好来解决limit 分页慢的问题:

假设 一个Solr查询按id 降序排序返回,假设返回10W行记录,前5W条记录可以随机分页查询到,但后面

5W条记录很难随机分页查询到,造成这个问题的原因是按id降序返回,如果适当修改一下查询语句,速度可

能会有所提高,因为Solr查询每次都会返回总的记录条数,这个总的记录条数是已知的, 记为total, 作如下处

理:如果start 小于等于 (total >> 1),则从前往后读;否则就从后往前读,然后,再把返回的结果逆序,显示

即可,伪代码如下;

  1. if start <= (total >> 1)
  2. query order by id desc limit start, rows;
  3. else
  4. calculate new start as start';
  5. calculate new rows as rows';
  6. query order by asc limit start', rows';
  7. reverse the return data;
  8. end

程序中相关代码:

  1. // 是否是按id升序查询, 默认是false
  2. boolean isAscend = false;
  3. // 升序或降序查询判断
  4. if (totalCount == 0) {
  5. isAscend = false;
  6. } else {
  7. if (start >= (totalCount >> 1) ) {
  8. isAscend = true;
  9. }
  10. }
  11. if (!isAscend) {
  12. realStart = start;
  13. realRows = rows;
  14. } else {
  15. Integer count = totalCount.intValue();
  16. realStart = (start + rows)>= count? 0 : (count - (start +rows));
  17. realRows = (start + rows)>= count? (count - start + 1) : rows;
  18. }
  19. solrQuery.setStart(realStart);
  20. solrQuery.setRows(realRows);
  21. if (!isAscend) {// id降序
  22. solrQuery.setSort("id", ORDER.desc);
  23. } else { // id 升序
  24. solrQuery.setSort("id", ORDER.asc);
  25. }
  26. // 逆序处理
  27. if (isAscend) {
  28. int size = syslogVOList.size();
  29. int left = 0;
  30. int right = size - 1;
  31. while (left < right) {
  32. SyslogVO leftSyslogVO =syslogVOList.get(left);
  33. SyslogVO rightSyslogVO =syslogVOList.get(right);
  34. syslogVOList.set(left, rightSyslogVO);
  35. syslogVOList.set(right, leftSyslogVO);
  36. left ++;
  37. right --;
  38. }
  39. }

经过这个过程的处理之后,向后翻页查询的速度快了很多,至少不会出现宕机的现象;

查询页面如下:

在相同的条件下:

优化后Solr查询的时间:

优化前mysql的查询时间:

其实这个技巧在mysql分页查询,数据量非常大的时候也适用;

转载于:https://www.cnblogs.com/cuihongyu3503319/p/9473471.html

Solr优化案例分析相关推荐

  1. Day814.电商系统表设计优化案例分析 -Java 性能调优实战

    电商系统表设计优化案例分析 Hi,我是阿昌,今天学习记录的是关于电商系统表设计优化案例分析. 如果在业务架构设计初期,表结构没有设计好,那么后期随着业务以及数据量的增多,系统就很容易出现瓶颈. 如果表 ...

  2. 崔华 oracle简历,2013数据库大会:崔华-基于Oracle的SQL优化案例分析

    2013数据库大会:崔华-基于Oracle的SQL优化案例分析 崔华的新书即将出版,其数据库大会上的演讲也非常精彩,他的新书十分值得期待. 2013年中国数据库技术大会第二天的"Oracle ...

  3. Spark的性能优化案例分析(下)

    前言 Spark的性能优化案例分析(上),介绍了软件性能优化必须经过进行性能测试,并在了解软件架构和技术的基础上进行.今天,我们通过几个 Spark 性能优化的案例,看一看所讲的性能优化原则如何落地. ...

  4. SQL性能优化案例分析

    这段时间做一个SQL性能优化的案例分析, 整理了一下过往的案例,发现一个比较有意思的,拿出来给大家分享. 这个项目是我在项目开展2期的时候才加入的, 之前一期是个金融内部信息门户, 里面有个功能是收集 ...

  5. Spark源码性能优化案例分析

    本篇文章枚举了几例常见的问题并给出了优化方案,推荐了两套测试性能优化工具 问题: Spark 任务文件初始化调优 资源分析,发现第一个 stage 时间特别长,耗时长达 14s , CPU 和网络通信 ...

  6. Mysql 索引优化分析_如何优化MySQL的性能?从索引方面优化案例分析

    今天我们来讲讲如何优化MySQL的性能,主要从索引方面优化. 建表 //建表 CREATETABLEIFNOTEXISTSstaffs( idINTPRIMARYKEYAUTO_INCREMENT, ...

  7. 性能为王:SQL标量子查询的优化案例分析

    本篇整理内容是黄廷忠在"云和恩墨大讲堂"微信分享中的讲解案例,SQL优化及SQL审核,是从源头解决性能问题的根本手段,无论是开发人员还是DBA,都应当持续深入的学习SQL开发技能, ...

  8. HBase优化案例分析:Facebook Messages系统问题与解决方案

    HDFS设计的初衷是为了存储大文件(例如日志文件),面向批处理.顺序I/O的.然而架设在HDFS之上的HBase设计的初衷却是为了解决海量数据的随机读写的请求.把这两种设计初衷截然相反的组件怎么揉在一 ...

  9. 视图优化oracle,干货|Oracle复杂视图优化案例分析

    在使用Oracle数据库过程中,视图是作为数据库对象存在的,因而,在创建了这样的视图后,就可以通过工具或者数据字典来查看视图的相关信息.视图来源于表,所有对视图数据的修改最终都会被反映到视图的基表中, ...

  10. 阿里巴巴网站的搜索引擎优化案例分析

    阿里巴巴是国内最早进行搜索引擎优化的电子商务网站,到目前为止也是网站优化总体状况最好的大型B2B电子商务网站之一.阿里巴巴的搜索引擎优化水平远远高于行业平均水平. 阿里巴巴中国站(china.alib ...

最新文章

  1. 像素颜色JavaFX示例--简易图片处理工具
  2. Linux - SVN下载项目
  3. Win7实用技巧之五库功能妙用
  4. 工作中这些实用的小技巧,90%的程序员不知道
  5. python实现ping命令_[小菜随笔]python tkinter实现简单的ping命令
  6. odoo基础数据加载
  7. Spring容器扩展机制
  8. STL 中的容器们(四)
  9. ES6 iterator 迭代器
  10. 多线程在Java项目中的使用案例(笔记)
  11. 《机器学习实战(第二版)》学习记录
  12. c语言程序设计第五版第四章例题
  13. PMP每日一练 | 考试不迷路-5.13
  14. 看不见世界的程序员,开发了一款“吃鸡”
  15. Oracle数据库,创建表并给表、字段添加注释
  16. 手机通讯原理的工作原理
  17. error uploading crisocket: timed out waiting for the conditionswapoff -a # will turn off the swap
  18. python背诵技巧_精选22个Python实用技巧,秀技能必备这份技术列表!
  19. 小车自动往返工作原理_自动往返小车
  20. Linux的文件目录结构

热门文章

  1. pythonATM,购物车项目实战_补充5-interface接口
  2. kettle的行转列主键用法详解(正规化 宽表到窄表的过程)
  3. oracle不能插入,oracle – 在过程中截断和插入不能一起工作
  4. 简易计算器里的小数点在程序中怎么表示_收藏!计算器使用攻略
  5. STM32中用 stop 模式 配合低功耗模式下的自动唤醒(AWU) 能否实现FreeRTOS tickless 模式...
  6. IDEA快捷键拆解系列(七):Analyze篇
  7. 201621123053《Java程序设计》第三周学习笔记文章
  8. 转 PHP函数---$_Get()和$_Post()的用法
  9. 部分转 Java读取ini配置
  10. 网站发布助手V1.1 (去年写的简单小工具)