ElasticSearch关于数据的操作

基本概念

  • 节点(node):一个运行着的ES实例
  • 集群(cluster):是由一个或多个节点(node)组合成的集合
  • 索引(indexing):动词,指在ES上存储数据的过程
  • 索引(index):名词,类型存在于索引中
  • 类型(type):文档属于一种类型
  • 文档(document):每条记录就是一个文档
  • 分片(shard):索引(index)实际上由一个或者多个分片组成的逻辑空间
    如果把ES数据库的名词术语与MySql数据库名词术语对照,大致如下表:
MySQL ElasticSearch
数据库(Database) 索引(Index)
数据表(Table) 类型(Type)
行(Row) 文档(Document)
列(Column) 字段(Field)

ES数据库的名词术语是学习ElasticSearch的基础,也是初次接触ElasticSearch的初学者最容易搞混淆的地方,尤其索引和类型最容易弄混,可以简单记为索引>类型,务必认真理解,这样在接下的讲解中涉及到这些术语时可以保持思路的清晰。

关于数据的操作

对ES数据的操作,可以用http请求的简单请求,或者DSL(Domain Specific Language)语言指定json请求体发送请求。DSL语言是ES特有的,类似于MySql中的SQL语句一样。

索引(增加操作)

动词,向ES增加一条文档的过程就是索引操作,类似于MySql的Insert操作。在ElasticSearch用户指定的文档字段以外,ES还有一些辅助字段用于标识每一条的文档。

  • _index字段:数据存储的ES索引名
  • _type:数据存储的ES类型名
  • _id:文档的ID,与索引和类型可以唯一标示一个文档,创建文档是可以自定义_id,如果不指定由ES自动生成,自动生成的ID有22个字符长,URL-safe, Base64-encoded全局唯一的字符串标识符。
  • _version:每个文档都有版本号,文档变化(包括删除)都会使_version增加,版本在版本控制的同时可以启动乐观锁的作用,在之后小节中详细讲解_version如何控制并发操作。

在实践中要特别注意,ES的索引操作与MySql的Insert操作不同之处在于,如果索引时文档已经存在,新的文档将会覆盖旧文档,而不是类似MySql的主键冲突异常。

更新

文档在ES中是不可变的。如果需要更新的文档已经存在,我们只能重建索引替换掉它。在内部实现中ES将旧文档标记为删除,旧文档不会立即消失,只是外部不能再次访问到。ES会在用户继续索引更多数据时清理被删除的文档。
ES提供更新的API——update API。update操作不是原子性的,ES更新文档局部时的操作依次是:检索--修改--重建索引。
具体的实现过程如下:

  1. 从旧文档中检索JSON
  2. 修改它
  3. 删除旧文档
  4. 索引新文档

删除

如上所述,ES删除一个文档不会立即从磁盘上移除,而是被标记成已删除。之后,ES会在用户继续索引更多数据时清理被删除的文档。

更新时产生的冲突

因为ES更新操作具有非原子性,在检索(retrieve)和重建索引(reindex)之间会存在一个时间间隔,这样在对ES请求时会存在请求冲突的问题,当多个更新请求同时到来,最后执行结束的请求可能是在已经失效的数据上进行的操作,这样结果自然大概率是错误的。

在ES中为了避免冲突和数据的丢失,在更新操作过程中的检索阶段(retrieve),同时检索当前文档的_version,然后重建索引(reindex)时校验_version,如果其他线程在这个阶段修改了文档,那么_version将不能被匹配,更新失败。

对于像增加计数这种顺序无关的操作时,可以设置表示重试次数的retry_on_conflict参数,多次重试更新。而对于顺序非常重要的操作时,可以使用last-write-wins update API(保留最后更新),这是一个乐观并发控制(optimistic concurrency control)的机制,接受一个version参数指定需要更新的文档的版本。

批量请求操作

批量操作在ES中不具有原子性,每条批量操作命令都是拆分成单条请求的,合并多个请求是为了减少多个单条请求的网络开销。

在ES API中常用的bulk API就是批量操作请求,拆分的每个请求都是独立互不影响的。在实践中需要特别注意的是bulk请求会加载到接受我们请求的节点内存中,所以请求越大,给予其他的请求内存就越小,性能反而不会因为减少了IO操作而提升,事实上性能下降。官方建议一个批次在1000~5000个文档之间,如果你的文档非常大,可以使用较小的批次,一个好的批次最好保持在5-15MB大小间。

版本控制---冲突的处理

多个线程同时请求一份文档时,只有最后索引的值会生效,其他先前索引的值均失效。如果对于多并发不加以控制就可能产生一系列不可预知的并发冲突引起的数据异常。

例如双十一的促销活动,电脑店老板有10台低价促销电脑,

  • 当同一时刻有两位买家下单,两个请求都读到库存是10,都在成功下单之后系统将库存减1后,此时为9写回ES中,那么最终显示的库存为9,而实际上卖出了两台。
  • 当同时多位买家拍下电脑,而其中一位买家因为系统延迟导致减后的库存值没有及时写回到ES中,这样当这位买家成功写回的时候可能将已经卖完的库存0,而实际写回的是他下单时库存减1的值。

问题由于没有合理的并发控制导致数据操作产生错误。处理并发控制的方法大致有两种:

  1. 悲观并发控制(Pessimistic Concurrency Control):认为冲突经常发生,对每一条请求均加锁进行并发控制。
  2. 乐观并发控制(Optimistic Concurrency Control):假设冲突不经常发生,不用加锁,每次更新会先检查有没有其他线程更改数据,如果没有则更新,如果已被更改,则执行回滚操作。

哲学中世界是处于矛盾之中,同样ElasticSearch即是同步的又是异步的,因为ElasticSearch是分布式的,每当请求到来会被分发复制到集群的其他节点中,网络复杂环境加上ES复制的请求都是平行发送的不存在先后的概念,这样每条复制请求都将是无序地到达目的地。为了保证老版本的文档永远不会覆盖新的版本,ES使用的是乐观并发控制,文档中的_version字段可以保证新的版本不会因为冲突而丢失,如果当前请求的版本号不是最新的,那么这条请求将被忽略。客户端请求时可以指定_version,每次修改操作都会校验文档_version是否匹配,不匹配不执行请求。

_version是ES生成的自增数字。为方便用户对ES在实际中的使用,_version也可以由客户端指定。实践中一种ES常见的使用场景,其他的数据库做为主数据库,同步数据至ES中用于搜索,如果多线程同时同步,就会产生并发冲突,需要为主数据库中加上版本号字段(或者从1递增,或者时间戳等),在同步程序利用这个字段作为同步ES指定的版本号,这种外部版本号与之前说的内部版本号在处理的时候有些不同。它不再检查_version是否与请求中指定的一致,而是检查是否小于指定的版本。如果请求成功,外部版本号就会被存储到_version中

搜索时的分页

最后聊一下搜索时经常用到的分页操作。在搜索ES文档的过程中可能需要取出指定页数指定数量的文档,ES对分页的处理经常涉及多个分片,每个相关分片按照分页要求准备排序好的所有文档,之后集中所有分片的结果重新排序再截取分页要求的文档数据

例如,全部文档按照_ID排序检索出每一页包含50个文档的第100页数据,集群中有主分片10,这样每个参与的分片会返回5000条文档,集中起来50000条数据再排序,取出第100页的50条文档既4950~5000区间的数据,将余下的49950条数据遗弃。随着分页的深入,系统性能的消耗成倍增长。所以在使用ES的分页功能时要谨慎。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容