ES数据延迟解决方案

需求背景

项目中有一个页面,需要在编辑后原地刷新页面。也就是编辑信息,点保存之后,前端会自动刷新页面。

技术方案

  1. 选择es作为查询数据源。

如果使用mysql作为查询数据源,需要join 3个表,而且where条件非常复杂,而且条件包含姓名左右模糊搜索(like '%xxx%'),性能肯定很差。
因此选择es作为查询数据源

  1. 点击保存之后,保存接口先把数据存到mysql,再推到es。

推es的方案,选择用RestHighLevelClient手动双写,而不是binlog。
因为一个es索引对应mysql多张表,如果用binlog,很难保证数据完整性。
另外,我们的写操作入口比较少,手动双写工作量不是很大。

  1. 保存操作完成之后,发布一个事件,监听器监听到事件后,异步把数据推送es。

1). 用spring的事务管理器,控制发布事件的时机在保存操作事务结束后,否则监听器可能查不到最新数据。
2). 发布事件的技术选型
- 如果发布器跟监听器在同一个微服务,可以用内存事件(java提供了观察者模式的api,参考java.util.EventListener)
- 如果发布器跟监听器在不同微服务,可以用mq
3). 用本地消息表保证事件at least once语义。
- 在保存操作的事务里,向本地消息表插入一行事件,状态初始化为init
- 监听器的逻辑,如果执行成功,把本地消息表的时间状态改成executed_success
- 监听器的逻辑,如果执行失败,把本地消息表的时间状态改成executed_fail
- 如果保存操作的事务成功了,那么事件在本地消息表肯定存在记录,增加一个job定时扫描本地消息表中状态为非init的记录,并重试。
4). 如果使用mq发布事件,如何保证消息一定发送成功?
- 如果mq支持事务消息(比如rocketmq),可以使用事务消息
- 如果mq不支持事务消息,可以用本地消息表

  1. 监听器的逻辑,大约需要1.5s,也就是说,保存操作的请求200后,还有约1.5s的数据延迟,如果这1.5s内,前端自动刷新页面,拿到的数据是不准的。

1). 使用RestHighLevelClient把数据推到es本质上是一个http请求,请求200,不代表es可以马上查询到数据。
2). 数据推到es后,数据只是存放在内存,等待一段时间,才会写入segment,然后才可以搜索到。
3). 这个时间间隔由es服务端的refresh_interval参数控制,这个参数默认是1s,SRE要求最低也是1s,否则可能把集群打挂。另外,客户端也可以设置写入索引后的刷新策略,RefreshPolicy.IMMEDIATE表示立即刷新。
4). 写入segment,相当于建立倒排索引,一个倒排索引分成多个segment。
5). 监听器的逻辑,有3部分耗时,这3部分耗时合计,绝大部分情况下在1.5s内
- 发送http请求,把数据推送es
- 1s的时间间隔,数据才写入segment
- 写入segment本身有耗时

es数据延迟解决方案

方案 技术实现 优点 缺点
方案一 用户操作完成后,马上刷新页面,查es 前后端实现简单,后续运维成本低 数据有延迟,产品不接受
方案二 用户操作完成后,前端sleep 1.5s后再刷新页面,查es 后端实现简单 涉及的接口较多(当前页面有5个写接口,1个读接口),前端实现复杂
方案三 从es捞id,其他信息从mysql查 查询es的筛选条件,本身就是有延迟的字段,因此从es捞出的id是不对的
方案四 保存接口执行完业务逻辑后,往redis set一个key,表示当前登录用户执行了保存操作,ttl设置为1.5s;查询接口执行业务逻辑前,判断key是否存在,若存在,从mysql查询,否则从es查询 可以解决数据延迟 需要维护mysql与es两套查询逻辑,日后需求有变更,两套方案都要改
方案无 保存接口执行完业务逻辑后,往redis set一个key,表示当前登录用户执行了保存操作,ttl设置为1.5s;查询接口执行业务逻辑前,判断key是否存在,若存在,sleep 1.5s 可以解决数据延迟 保存接口与查询接口没有解耦,查询接口需要关注保存接口的逻辑
方案六 查询接口加一个isReadAfterWrite字段,标识本次请求是否是用户操作完成后的查询。如果isReadAfterWrite=true,后端sleep 1.5s,再查es;如果isReadAfterWrite=false,正常执行逻辑 可以解决数据延迟

综合考虑后,选择方案六

思考

  1. 为了保障数据一致性,就要牺牲部分耗时
  2. 接口的耗时不用追求绝对的最优,要在保障业务逻辑的可用性前提下,尽量耗时短
  3. 如果跟业务逻辑可用性冲突时,top1需要保障的是业务逻辑的可用性
  4. 如果一个页面需要查es,筛选条件应该是不可变的字段,比如姓名、国籍这种,这样才可以用es捞id,其他信息从mysql查
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容