背景

公司有一个业务场景,数据库的修改需要同步到Elasticsearch里,但是该场景的修改频率有点高,经常会出现一条记录短时间内多次的变化,如果每次变化都作为一次ES同步任务,那ES肯定是受不住的。

思路

通过估算请求规模,主要有如下2方面的解决思路:

  • 高频变化去重:因为同一条记录短时间内多次变化,其实同步一次最终的状态即可,所以可以考虑牺牲一定的实时性,在一定时间窗口内做变化通知的去重。
  • 批量导入:每条记录变化作为独立请求推送给ES,实际上远不如多条记录批量推送ES的吞吐要高。

方案

  • 在线去重:因为在线业务本身是高频的,所以需要一个高频的存储介质来实现去重,想到redis的set/zset数据结构。
  • 离线批量:利用离线JOB定时的将一段时间内去重的变动集合推送给ES,其核心问题在于在线set集合如何离线化,保证互不影响。

整体架构如下:

假设变动的是用户的积分等高频资产信息,那么在线部分一旦数据库发生变动,则将用户uid向zset_w在线集合写入,可以实现实时去重。

离线JOB则首先检查zset_r离线集合是否有剩余变动任务未处理,若zset_r集合为空则执行redis的rename操作将在线集合zset_w重命名为zset_r,这个过程对redis来说是原子性的。

此后离线JOB继续处理zset_r中已经去重的变化uid集合,而在线部分继续向新的zset_w集合添加最新变动的uid即可,如此往复。

优化

随着在线高频变更量的增多,该方案可以实施横向扩展,即准备N对(zset_w、zset_r)并令在线部分按uid打散流量,从而可以为每一对zset启动独立的离线JOB,实现并行处理。

鉴于在线部分操作redis异常导致通知丢失,可以通过长周期的全库离线补偿实现,在此不做说明。

结论

该业务场景的思想本质包含了2点:

  • 流式转批量 换取更高的吞吐。
  • 大问题拆小 实现横向的扩展。

总是思考是否有更简单的方案,做到简单可依赖。


利用redis实现elasticsearch入库去重的更多相关文章

  1. Python分布式爬虫打造搜索引擎完整版-基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站

    Python分布式爬虫打造搜索引擎 基于Scrapy.Redis.elasticsearch和django打造一个完整的搜索引擎网站 https://github.com/mtianyan/Artic ...

  2. 基于Redis的BloomFilter算法去重

    BloomFilter算法及其适用场景 BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合.因为基于H ...

  3. 利用Redis解决Url过长的问题

    做网站,接手别人的代码,发现url有时候会过长导致页面直接翻掉. 后来想了一下可以利用redis将太长的地方暂存,加载页面时获取即可. 存Redis: /// <summary> /// ...

  4. Hadoop阅读笔记(二)——利用MapReduce求平均数和去重

    前言:圣诞节来了,我怎么能虚度光阴呢?!依稀记得,那一年,大家互赠贺卡,短短几行字,字字融化在心里:那一年,大家在水果市场,寻找那些最能代表自己心意的苹果香蕉梨,摸着冰冷的水果外皮,内心早已滚烫.这一 ...

  5. 利用Redis cache优化app查询速度实践

    注意:本篇文章译自speeding up existing app with a redis cache,如需要转载请注明出处. 发现问题 在应用解决方法之前,我们需要对我们面对的问题有一个清晰的认识 ...

  6. [翻译]利用REDIS来搭建可靠分布式锁的提议

    本系列都是翻译REDIS作者的博文  另外加上我自己的一点点理解  希望有问题大家一起讨论 http://antirez.com/news/77 原文地址 在利用REDIS做分布式锁时基本持有2种观点 ...

  7. 利用redis写webshell

    redis和mongodb我之所见 最近自己在做一些个人的小创作.小项目,其中用到了mongodb和redis,最初可能对这二者没有深入的认识.都是所谓的“非关系型数据库”,有什么区别么? 实际上,在 ...

  8. 如何利用redis来进行分布式集群系统的限流设计

    在很多高并发请求的情况下,我们经常需要对系统进行限流,而且需要对应用集群进行全局的限流,那么我们如何类实现呢. 我们可以利用redis的缓存来进行实现,并且结合mysql数据库一起,先来看一个流程图. ...

  9. 利用redis实现分布式锁知识点总结及相关改进

    利用redis实现分布式锁知识点总结及相关改进 先上原文,本文只为总结及对相关内容的质疑并提出若干意见,原文内容更详细https://www.cnblogs.com/linjiqin/p/800383 ...

随机推荐

  1. Adding a view

    在添加View之前,之前的页面是下面这个样子,需要注意的是浏览器标题,以及浏览器的内容 https://docs.asp.net/en/latest/tutorials/first-mvc-app/a ...

  2. python spark 通过key来统计不同values个数

    >>> rdd = sc.parallelize([("), ("b", 1), ("a", 1), ("a", ...

  3. 深入理解groupByKey、reduceByKey区别——本质就是一个local machine的reduce操作

    下面来看看groupByKey和reduceByKey的区别: val conf = new SparkConf().setAppName("GroupAndReduce").se ...

  4. Hdu-2892 area 计算几何 圆与凸多边形面积交

    题面 题意:有一个凸多边形岛屿,然后告诉你从高空(x,y,h)投下炸弹,爆炸半径r,飞机水平速度和重力加速度,问岛屿被炸了多少 题解:算出来岛屿落地位置,再利用圆与凸多边形面积交 #include&l ...

  5. 介绍一个简单的Parser

    我们已经学习了怎样创建一个简单的Monad, MaybeMonad, 并且知道了它如何通过在 Bind函数里封装处理空值的逻辑来移除样板式代码. 正如之前所说的,我们可以在Bind函数中封装更复杂的逻 ...

  6. 用命令行在本地创建一个库并上传到Github

    1  如何在本地创建一个仓库并上传到github? 基本步骤: $ mkdir blog //在桌面上创建一个叫"blog"的目录 $ cd blog //"cd blo ...

  7. SurfaceView加载长图

    1:SurfaceView加载长图,移到.可以充当背景 效果截图 2:View (淡入淡出动画没实现:记录下) package com.guoxw.surfaceviewimage; import a ...

  8. zmodem使用方法

    无论有xshell还是secureCRT连接linux的时. 默认都用一个zmodem可以帮助window和linux之间传输文件 很方便和实用的工具. 不过默认是无法使用的 需要安装lrzsz软件 ...

  9. VS2012编译PCL1.70的过程

    以防博主删除文档,重新copy一遍... 关于个人的几个注意事项: 对于boost,可以使用vc100的库,来编译VC110的代码: 对于确实的包含,一个一个添加,要耐心等待!!! 原文链接:http ...

  10. 杭电2060WA

    #include<stdio.h> int main() { int n,num,p,q,i,a[]={2,3,4,5,6,7}; scanf("%d",&n) ...