spring整合es,logstash,mysql实践

一、ElasticSearch简介

ES是一款分布式的全文检索框架,底层基于Lucene实现,天然分布式,p2p架构,不支持事务,采用倒排索引提供全文检索。较为广泛的应用于全文检索和统计分析的聚合查询中。

二、ES较之于mysql的优势

ES是一个支持分布式的框架,它的每个node都可以接收读request,然后该node会把request分发到含有该index的shard的节点上,对应的节点会查询、并计算出符合条件的文档,排序后结果汇聚到分发request的node(所以查询请求默认会轮循的将发送到各个节点上,防止请求全部打到一个节点),由该node将数据返回给client。相比于mysql的扩展性较差的单机模式具有很强的性能提升。
再者,ES具有较强的聚合查询能力,虽然mysql也提供有group by等用来聚合查询的语句,但是遇到较为复杂的统计查询时,mysql显然是力不从心的,这时候es的聚合查询能力的优势就显得尤为重要了。
举个例子:倘若我们要统计一批数据中startDate和endDate时间范围内每七天一次统计的数据条数,并将时间作为横轴,数据条数作为纵轴供前端渲染显示,这时候mysql的简易聚合查询能力就会显得很难,即使写出了这样的sql语句,也将会很复杂,但我们利用es原生的聚合查询api就可以很容易实现这个需求。

curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/students/_search?pretty=true' -d '
    {
      "aggs" : {
        "sentdate_range_search" : {
          "date_range" : {
            "field" : "updateTime",
            "time_zone": "UTC",
            "interval":"7day",
            "format" : "yyyy-MM-dd HH:mm:ssZZ",
            "ranges" : [
              { "from" : "2010-05-07 11:22:34+0000", "to" : "2011-05-07 11:22:34+0000"}
            ]
      }
    }
  }
}'

三、es本地下载启动

brew install elasticsearch

再执行elasticsearch命令启动es:默认端口号为9200

四、mysql数据表建立及logStash配置实现mysql、es数据同步

首先在本地建立一张数据表:

CREATE TABLE student(
  id INT PRIMARY KEY AUTO_INCREMENT ,
  name VARCHAR(200) not null,
  shcool  VARCHAR(200) not null,
  update_time datetime not null,
  have_money bigint not null,
) 

logStash安装配置:

brew install logstash
cd /usr/local/Cellar/logstash/7.12.1/bin

编写配置文件:

input {
      jdbc {
      ### 连接的mysql数据库相关信息
        jdbc_connection_string => "jdbc:mysql://127.0.0.1:3306/test"
        jdbc_user => "root"
        jdbc_password => "***"
		### jdbc驱动jar包
        jdbc_driver_library => "/usr/local/Cellar/logstash/7.12.1/libexec/logstash-core/lib/jars/mysql-connector-java-8.0.25.jar"
        jdbc_driver_class => "com.mysql.jdbc.Driver"
        jdbc_paging_enabled => "true"
        jdbc_page_size => "50000"
		###  用于同步的字段,上面建的mysql表中的update_time字段
        tracking_column => update_time
        record_last_run => true
        ### 在这个目录下建一个文件用来存储上一次数据同步的时间
        last_run_metadata_path => "/usr/local/opt/logstash/lastrun/.logstash_jdbc_last_run"
        jdbc_default_timezone => "Asia/Shanghai"
        ### 当表中的update_time时间大于上一次同步的时间,将其加载到es中
        statement_filepath => "SELECT * FROM goods  WHERE update_time > :sql_last_value"
        clean_run => false 
        ### 每一分钟同步一次
        schedule => "* * * * *"
        type => "std"
      } 
} 
output {
    elasticsearch {
    ### es地址和索引、type
        hosts => "http://localhost:9200"
        index => "students"
        document_type => "student"
        document_id => "%{id}"
    }
    stdout{
        codec => json_lines
    }
}    

启动logstash

./logstash -f jdbc.conf

五、Springboot整合es

新建Springboot项目,项目目录
在这里插入图片描述
配置文件

spring:
  main:
    allow-bean-definition-overriding: true
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: Lliulei919
  jpa:
    show-sql: true
  data:
    elasticsearch:
      cluster-name: ll
      cluster-nodes: 127.0.0.1:9200
      repositories:
        enabled: true

jpa循环往sql中插入2000份数据

public void startInjectData() {
        List<Student> list = new ArrayList<>();
        Date currentDate = new Date();
        for(int i=0;i<2000;i++){
            Student student = new Student();
            student.setName("zhangsan" + i);
            student.setSchool("Cleton" + i);
            student.setHomeTown("beijing");
            student.setHaveMoney(2000L + i * 10);
            student.setUpdateTime(new Date(currentDate.getTime() - 1000 * i * 60 * 60 * 24) );
            list.add(student);
        }
        studentSqlRepository.saveAll(list);
    }
public interface StudentRepository extends JpaRepository<Student,Integer> {
    Integer countByHaveMoneyBetween(Long start, Long end);
}

springBoot整合es进行简单查询

public interface StudentEsRepository extends ElasticsearchRepository<StudentVO,Integer> {
}

ElasticsearchRepository具有基础的crud查询方法,直接调用即可操作es中的数据,与jpa类似

进行复杂聚合查询
选用
@Autowired private ElasticsearchRestTemplate esTemplate;进行聚合查询

AggregationBuilder aggregation =
                AggregationBuilders
                        .dateHistogram("es_count")
                        .field("update_time")
                        .fixedInterval(DateHistogramInterval.days(7));

查询条件:

NativeSearchQuery searchQueryBuilder = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.rangeQuery("update_time").from(startDate).to(endDate))
                .addAggregation(aggregation)
                .build();

这样的聚合查询条件也就可以解决‘统计一批数据中startDate和endDate时间范围内每七天一次统计的数据条数,并将时间作为横轴,数据条数作为纵轴供前端渲染显示’这个需求了
所以对于较为复杂的统计查询,只需要编写聚合查询条件,即可相比于mysql得到较为优秀的查询性能了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值