es是如何判度写入的记录是插入还是更新?
code4j 回复了问题 • 5 人关注 • 3 个回复 • 3884 次浏览 • 2019-07-20 16:36
es更新一条数据完全相同的内容的记录,是否会和原记录比较?
HelloClyde 回复了问题 • 2 人关注 • 1 个回复 • 2798 次浏览 • 2019-07-18 17:04
求助,index的时候碰到ElasticSearch 503的问题
bellengao 回复了问题 • 2 人关注 • 1 个回复 • 2609 次浏览 • 2019-07-21 12:39
生产上的ES每过10分钟,全索引都会被查一次,测试环境没有该现象,有没带佬遇到过
dotNetDR_ 回复了问题 • 3 人关注 • 2 个回复 • 1646 次浏览 • 2019-07-22 13:27
Lucene doc value结构自己的一点理解
code4j 回复了问题 • 5 人关注 • 3 个回复 • 5249 次浏览 • 2019-07-31 14:57
使用spark向elasticsearch中写入数据会超出本来的数量
HelloClyde 回复了问题 • 2 人关注 • 1 个回复 • 1556 次浏览 • 2019-07-18 08:59
es如何做到 根据分词匹配度 和 另一个字段 排序
HelloClyde 回复了问题 • 4 人关注 • 1 个回复 • 8421 次浏览 • 2019-07-18 09:16
es如何给greenplum创建索引
匿名用户 回复了问题 • 2 人关注 • 2 个回复 • 1842 次浏览 • 2019-11-21 17:51
java计算es某一个索引库占用磁盘大小的API是什么
bellengao 回复了问题 • 2 人关注 • 1 个回复 • 1760 次浏览 • 2019-07-17 18:38
Elasticsearch7.2设置邮箱账号问题
printf_uck 回复了问题 • 2 人关注 • 1 个回复 • 1804 次浏览 • 2019-07-17 14:22
ES在windows下JVM Heap设置?ES提示Data to large
HelloClyde 回复了问题 • 2 人关注 • 1 个回复 • 1424 次浏览 • 2019-07-18 09:02
从MySQL建立Elasticsearch索引-索引
hufuman 发表了文章 • 0 个评论 • 5083 次浏览 • 2019-07-16 23:24
本文始发于知乎Elasticsearch专栏:[从MySQL建立Elasticsearch索引-索引](https://zhuanlan.zhihu.com/p/73802842)
接上文[从MySQL建立Elasticsearch索引-引言](https://zhuanlan.zhihu.com/p/73349672),本文介绍一下我们实现索引创建时的一些思路。
目标
框架以Jar包的形式提供,通过配置(XML)提供规则,支持插件开发,支持全量、增量等。
因为希望尽量减少开发量,所以不要求使用方提供平表,因此需要考虑如何将平表
概念
- 全量:即使用全部数据创建一个新的索引
- 增量:按照时间范围或者给定的规则,把变化的数据同步到ES
- 插件:本框架内定义了一个插件接口,用于特定需求自行开发,并接入到现有的配置文件中
- 分批参数:SQL中由框架填充的参数,类似${id}等
配置
以用户(users)为例,配置有三种文件:
- users.mapping,保存了索引的配置,每次全量的时候会读取本文件进行索引创建
- rule,规则文件,里面主要定义了对应SQL和插件的配置
- users-all.rule,全量规则,规则中以主表为主体,支持以Top、Limit的形式对数据进行分批获取,分批参数在SQL里可以定义为${id},框架会自动填充该值,以保证能够拉取到全量的数据
- users-inc.rule,按照时间范围进行增量,分批参数支持在SQL中使用${startTime}和${endTime}
- users-spec.rule,按照指定的主表的主键,获取数据及更新索引的操作
- users-partial.rule,框架接入了阿里的Canal,本规则定义了各种表变化时,如果取到主表Id,以使用spec进行数据更新
- users.plugin,以上的rule主要提供了主表数据的获取方法,plugin文件则提供了各种关联表的信息获取方式,可以使用SQL,或者自定义的插件
全量索引实现关键点
为了保证索引的性能、监控、正确性等,实现时进行了以下设计。
(一)索引的维护
ES使用分布式、Replica、Snapshot机制保证索引的有效及集群稳定性。我们综合考虑后决定放弃Snapshot机制,通过定时/不定时创建全新全量索引,索引名字以${indexName}-{yyyy-MM-dd}的格式定义。正进行全量的索引关联上${indexName}_F的别名,正在使用的索引关联上${indexName}的别名,这样代码里可以不用关心应该读取或者使用哪个索引,合适的场景使用合适的别名即可。
(二)索引的性能
此处专指创建索引的性能,ES的性能是老话题了。
首先,为了保证全量的性能,创建索引时会调整mapping参数,类似refresh_interval改成-1,number_of_replicas改成0,添加默认slowlog设置。
索引过程中,控制bulk请求体的总大小,保证合适的分批大小的数据一并提交到ES。如果失败简单重试三次,如果三次都失败则认为失败,退出并删除当前索引,以保证线上ES数据干净准确。
(三)索引的变更
索引完成后,检查当前索引文档数和正使用索引文档数差异,如果大于配置的阈值,则认为此次索引创建有问题,删除索引并退出;做强制合并,减少segments数,提高搜索性能;恢复refresh_interval、number_of_replicas等设置;等待新索引状态变成GREEN后,将${indexName}切换到新的索引上,以使新索引生效。
最后,检查以${indexName}-{yyyy-MM-dd}格式命名的索引有几份,将多于指定个数的较老的索引删除,将多于指定个数的索引状态改为Close。这样可以尽可能提供磁盘内存利用率,减少不必要的损耗,又能在一定程度上保证数据可用。
以上,即完成了全量索引的创建。
增量索引实现关键点
增量索引因为场景比较多,所以规则也分了几种:
- users.mapping,保存了索引的配置,每次全量的时候会读取本文件进行索引创建
- inc,使用${startTime}和${endTime}在SQL中代替时间范围,框架会自动保存上次执行时间,以使整个增量整体不断滚动更新。实际使用时,因为有多个关联表导致SQL写起来比较复杂,以及部分增量数据过大,对DB有一定压力,因此不推荐使用此种方式。数据相对简单的场景可以使用。
- spec,在知道主表数据变化范围的时候使用,也是目前我们推荐的一种方式。使用主键查找数据,所有的表都是主键查询,影响范围也很明确。
- partial,针对canal做了单独封装的规则,用户获取canal的变化类型(更新、删除),变化的主表Id,用于使用spec的方式进行数据更新。
暂时没有使用部分更新的原因是,关联表与主表的映射关系比较复杂,有1:1,1:N,M:N;并且目前按照主键更新数据的方式,对DB等压力不大;加上spec的方式逻辑清晰,有利于维护和开发。
扩展性
SQL不是万能的,比方说我们部分数据需要从其他微服务取,或者SQL逻辑复杂建议代码实现,这时候就可以使用我们的插件机制了。默认框架提供了一个很强大的插件,支持Distinct、Merge、Mapping等功能,可以满足80%的关联数据的场景了。其他的场景以及需要微服务的场景,支持用户自己实现指定插件,通过配置文件,即可接入现有的框架体系中。以此能支持目前我们全部需求。
下一篇,我们将分享我们搜索模块的实现思路。
从MySQL建立Elasticsearch索引-引言
hufuman 发表了文章 • 0 个评论 • 2961 次浏览 • 2019-07-16 23:19
本文始发于知乎Elasticsearch专栏:[从MySQL建立Elasticsearch索引-引言](https://zhuanlan.zhihu.com/p/73349672)
日常工作里,因业务需要大量使用了Elasticsearch。为了简化索引的开发工作,我们需要一个易用可扩展的MySQL到ES的同步框架,在比较了可以找到的各种开源框架&工具后,我们还是选择自行研发了一个,名字简单粗暴:es-common。
背景
16年我接手了并负责了部门所有业务的搜索系统,旧搜索系统是基于Lucene自研实现的一个搜索框架,包含了平表创建、全量索引、增量索引、搜索引擎四个部分基础功能的封装;另有一个管理系统,用于配置索引、字典等信息。框架的实现思路是通过建立平表,简化索引创建的过程。
接手该系统以后,各业务出现井喷式发展,各种需求铺天盖地,同时该系统的不稳定性也开始作妖,最早三个人的小团队每天都疲于奔命。解决现有问题的同时,也在查找更好的解决方案。于是Elasticsearch进入视野。
基于JSON的交互、分布式、数据与逻辑隔离、开箱即用、稳定等特性,使我们确定了向ES转型的计划。每个点都是现有系统没有解决的问题,具体的点就不吐槽了。
选择
我们的需求有:
- 支持全量、增量建立索引,以使数据变更较快体现
- 支持更新指定文档,以处理突发问题
- 索引有版本控制,以防止出现问题无法快速回滚
- 尽量减少代码开发,减少出错概率,更专注业务
- 简单的出错处理,失败检测等
- 支持插件化开发,提供额外数据
- 支持简单的规则,类似合并同主键数据
- 域名、AUTH不可见,以满足安全要求
- 支持非MySQL来源的数据,因为微服务的存在,不是所有数据都能从DB获取到
当时的调用结果已经找不到了,那么按照现在可以搜索到的框架和工具来重新做调研好了。简单搜索了一下MySQL到ES的同步框架或者工具,有以下几个:
- [elasticsearch-jdbc](https://github.com/jprante/elasticsearch-jdbc)
- [elasticsearch-river-mysql](https://github.com/scharron/el ... -mysql)
- [go-mysql-elasticsearch](https://github.com/siddontang/ ... search)
- [logstash-input-jdbc](https://github.com/logstash-pl ... t-jdbc)
这几个工具通过简单的配置,即可建立索引,但分析我们的需求,有以下需求无法满足:
- [elasticsearch-jdbc](https://github.com/jprante/elasticsearch-jdbc)
- 需要提供DB的URL、User和Password等,我们公司由于安全的考虑,是无法拿到这些参数的;
- 有部分数据是通过微服务获取的,单纯的SQL是无法访问微服务的;
- 有的表数据量比较大,需要分片多JOB同时处理,JDBC在这点上操作比较麻烦;
- 增量是需要按照主键进行更新的,按照时间扫描对表压力比较大;
- 类似工具无法走常规发布,有一定的发布风险
基于以上原因,我们选择了自己研发了一个框架,用来满足我们的需求。下篇文章讲介绍es-common的实现思路。