热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

流计算技术实战超大维表问题

维度表,作为数据仓库里面的概念,是维度属性的集合,比如时间维、地点维;但这里要讨论流计算中的维度表问题,流计算中维表问题和数

维度表,作为数据仓库里面的概念,是维度属性的集合,比如时间维、地点维;

image

但这里要讨论流计算中的维度表问题,

流计算中维表问题和数据仓库中有所不同,往往是因为通过agent采集到的数据比较有限,在做数据业务的时候,需要先实时的把这些维度信息给补全;

这个问题其实就是,主数据流和多个静态表或半静态表之间的join问题。

image

在flink中称为side input问题,https://cwiki.apache.org/confluence/display/FLINK/FLIP-17+Side+Inputs+for+DataStream+API

 

解决维表问题考虑到点,

a. 对元数据库的读压力;如果分析程序有1000并发,是否需要读1000次

b. 读维表数据不能拖慢主数据流的throughput,每秒千万条数据量

c. 动态维表更新问题和一致性问题;元数据是不断变化的,如何把更新同步到各个并发上

d. 冷启动问题,如何保证主数据流流过的时候,维表数据已经ready,否则会出现数据无法处理

e. 超大维表数据会导致流量抖动和频繁gc,比如几十万条的实例数据,可能上百兆

 

下面谈谈我们解决这个问题的思路,

 

1. 最简单的版本,每个进程都会独立的去从元数据里面读取元数据;

这样的优点是简单,c,d问题天然解决;但只能适用于数据量较小的场景,否则并发太大,a,肯定就无法满足

image 

 

2. 随着业务量的扩大,处理程序的并发越来越大,1,很快会达到瓶颈

我们就采用新的方案,这个方案是在Jstorm环境实现的,用一个spout读,然后广播给所有的处理进程

image

这个方案主要解决a,c的问题,
但是也引入了d,e的问题,

解决d,Jstorm支持让某个spout在job启动后等待一段时间,所以可以让主数据流spout等待几分钟再开始读数据,这样保证数据到的时候,维表数据已经ready;这个解法每次重启job都要等好几分钟,体验挺差的,但是勉强可以work

e问题,一个spout广播超大维表到几百并发的线程,首先就是会队列满,因为jstorm发一份数据到所有并发的时候,是需要产生几百份真实数据在队列中的;然后GC也会很严重,因为大量的临时对象会产生释放,在传输和进程cache过程中,会导致业务抖动

这个问题只能增加内存和worker数来解决,否则job有可能会完全hang死

我们也用Chronicle Map(https://github.com/OpenHFT/Chronicle-Map)来尝试解决内存使用和gc的问题

 

BTW,有同学问,如果让数据和维表数据都 shuffle by key,是不是可以缓解这个问题
如果数据量比较小,可以考虑,但是对于我们的主数据流的数据量,是没法shuffle的,所以需要在每个并发上保留全量的维表信息

 

2.1 用Flink带替换Jstorm

Flink虽然在window,乱序,一致性等方面做了很大的改进,但是在这个问题上仍然没有很好的解,上面提到的side input也没有实现出来;

并且Flink随着更多的高层的封装,程序员的开发自由度是降低的,和JStorm比,所以如果用Flink解决上面的问题,没有本质变化,可能JStorm更麻烦;

需要用ConnectedStreams去joine数据流和side input流,
对于d问题,没法直接解决
对于e问题,因为flink对内存管理做的比较好,gc问题有所缓解,但是job抖动的问题还是会存在

因为广播这么大的数据,会中断主数据流的数据处理,也会大大增加checkpoint的时间,如下图,可以看到30分钟一次的同步

image image

 

BTW,Flink保障一致性,提供checkpoint机制,但也增加复杂性,这个地方处理不好会有很多问题
比如,如果在source中同步读数据库数据,如果读库的时间比较长,就会hang住主数据流,因为其他operator都会等它完成checkpoint,写JStorm的程序员需要注意这点,Flink需要更精细的控制,任何operator,任何并发的hang都会导致整个任务hang

我个人尝试使用flink本身的机制,statebackend,rocksdb等来更优雅的解决这个问题,但是没有发现比较好的方法,或者实现过于复杂

 

3. Redis版本

这其实是把1,2方法做了综合

使用redis来做cache,只用一个job,负责从元数据库同步数据到redis,这样就解决a,c

然后所有的并发都从redis直接查询需要的元数据,这样就解决d

对于b,在并发上做local cache,只有第一次需要真正查询redis,后续定期异步更新就好,不会影响到主数据流

对于e,因为现在不需要一下全量的读取维表数据到内存,用到的时候才去读,分摊了负载,也可以得到缓解

image 

该方案当前线上跑着,还算比较稳定

这个方案最大的缺点是增加依赖,对于需要全球多region大规模部署的应用,增加依赖是成本极高的
同时要额外保障redis和同步job的稳定性

BTW,这里不建议local cache用LRU,因为要考虑到当redis挂掉或同步job挂掉的时候,不能影响主数据流,所以我只会异步的更新local cache,但不去做过期,这样就算redis挂了,也只是影响更新的实例,大大降低故障发生概率

 

总结,

分享一下自己的一些实战经验,希望可以抛砖引玉,找到更合理,优雅的方案



推荐阅读
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了解决mysql 5.1启动问题的方法,通过修改my.ini文件中的相关配置,包括innodb_data_home_dir和skip-innodb等,可以解决启动问题。同时还介绍了如何调整内存池来存储metadata信息。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Python实现变声器功能(萝莉音御姐音)的方法及步骤
    本文介绍了使用Python实现变声器功能(萝莉音御姐音)的方法及步骤。首先登录百度AL开发平台,选择语音合成,创建应用并填写应用信息,获取Appid、API Key和Secret Key。然后安装pythonsdk,可以通过pip install baidu-aip或python setup.py install进行安装。最后,书写代码实现变声器功能,使用AipSpeech库进行语音合成,可以设置音量等参数。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
author-avatar
手机用户2502938311
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有