《银行的一天》演示日志处理保序、不丢、不重

日志处理是一个很大范畴,其中包括实时计算、数据仓库、离线计算等众多点。这篇文章主要讨论如何在实时计算场景中,如何能做到日志处理保序、不丢失、不重复,并且在上下游业务系统不可靠(存在故障),业务流量剧烈波动情况下,如何保持这三点。

为了能够方便理解,这里会使用《银行的一天》作为例子将概念解释清楚。在篇幅的末尾,我会介绍下日志服务LogHub功能,是如何与Spark Streaming、Storm Spout等配合,完成日志数据的处理过程。

问题定义

什么是日志数据?原LinkedIn员工Jay Kreps在《The Log: What every software engineer should know about real-time data's unifying abstraction》描述中提到:“append-only, totally-ordered sequence of records ordered by time”

  • Append Only:日志是一种追加模式,一旦产生过后就无法修改
  • Totally Order By Time:严格有序,每条日志有一个确定时间点。不同日志在秒级时间维度上可能有重复,比如有2个操作GET、SET发生在同一秒钟,但对于计算机而言这两个操作也是有顺序的

什么样的数据可以抽象成日志?

半世纪前说起日志,想到的是船长、操作员手里厚厚的笔记。如今计算机诞生使得日志产生与消费无处不在:服务器、路由器、传感器、GPS、订单、及各种设备通过不同角度描述着我们生活的世界。从船长日志中我们可以发现,日志除了带一个记录的时间戳外,可以包含几乎任意的内容,例如:一段记录文字、一张图片、天气状况、船行方向等。几个世纪过去了,“船长日志”的方式已经扩展到一笔订单、一项付款记录、一次用户访问、一次数据库操作等多样的领域。

在计算机世界中,常用的日志有:Metric,Binlog(Database、NoSQL),Event,Auditing,Access Log 等。

在我们今天的演示例子中,我们把用户到银行的一次操作作为一条日志数据。其中包括用户、账号名、操作时间、操作类型、操作金额等。

例如:

2016-06-28 08:00:00 张三 存款 1000元
2016-06-27 09:00:00 李四 取款 20000元

LogHub数据模型

为了能抽象问题,这里以阿里云日志服务下LogHub作为演示模型,详细可以参见日志服务下基本概念。

  • Log: 由时间、及一组Key,Value对组成
  • LogGroup: 一组日志的集合,包含相同Meta(IP,Source)等

两者关系如下:

  • Shard: 分区,LogGroup读写基本单元,可以理解为48小时为周期的FIFO队列。每个Shard提供 5 MB/S Write, 10 MB/S Read能力。Shard 有逻辑区间(BeginKey,EndKey)用以归纳不同类型数据
  • Logstore:日志库,用以存放同一类日志数据。Logstore是一个载体,通过由[0000, FFFF..)区间Shard组合构建而成,Logstore会包含1个或多个Shard
  • Project: Logstore存放容器

这些概念相互关系如下:

银行的一天

我们来以19世纪银行来举例子,城市里有若干用户(Producer),到银行去存取钱(User Operation),银行有若干个柜员(Consumer)。因为19世纪还没有电脑可以实时同步,因此每个柜员都有一个小账本能够记录对应信息,每天晚上把钱和账本拿到公司去对账。

在分布式世界里,我们可以把柜员认为是固定内存和计算能力单机。用户是来自各个数据源的请求,Bank大厅是处理用户存取数据的日志库(Logstore)。

  • Log/LogGroup:用户发出的存取款等操作
  • 用户(User):Log/LogGroup生产者
  • 柜员(Clerk):银行处理用户请求的员工
  • 银行大厅(Logstore):用户产生的操作请求先进入银行大厅,再交给柜员处理
  • 分区(Shard):银行大厅用以安排用户请求的组织方式

问题1:保序(Ordering)

银行有2个柜员(A,B),张三进了银行,在柜台A上存了1000元,A把张三1000元存在自己的账本上。张三到了下午觉得手头紧到B柜台取钱,B柜员一看账本。不对啊,你没有在我这里存钱?

从这个例子可以看到,存取款是一个严格有序的操作,需要同一个柜员(处理器)来处理同一个用户的操作,这样才能保持状态一致性。

实现保序的方法很简单:排队,创建一个Shard,终端只有一个柜员A来处理。用户请求先进先出,一点问题都没有。但带来的问题是效率低下,假设有1000个用户来进行操作,即使有10个柜员也无济于事。

这种场景怎么办?

  1. 假设有10个柜员,我们可以创建10个Shard
  2. 如何保证对于同一个账户的操作是有序的?可以根据一致性Hash方式将用户进行映射。例如我们开10个队伍(Shard),每个柜员处理一个Shard,把不同银行账号或用户姓名,映射到特定Shard中。在这种情况下张三 Hash(Zhang)= Z 永远落在一个特定Shard中(区间包含Z),处理端面对的永远是柜员A。

当然如果张姓用户比较多,也可以换其他策略。例如根据用户AccountID、ZipCode进行Hash,这样就可以使得每个Shard中操作请求更均匀。

问题2:不丢失(At-Least Once)

张三拿着存款在柜台A处理,柜员A处理到一半去接了个电话,等回来后以为业务已经办理好了,于是开始处理下一个用户的请求,张三的存款请求因此被丢失。

虽然机器不会人为犯错,在线时间和可靠性要比柜员高。但难免也会遇到当机、或因负载高导致的处理中断,因为这样的场景丢失用户的存款,这是万万不行的。

这种情况怎么办呢?

A可以在自己日记本上(非账本)记录一个项目:当前已处理到Shard哪个位置,只有当张三的这个存款请求被完全确认后,柜员A才能叫下一个。

带来问题是什么?可能会重复。比如A已经处理完张三请求(更新账本),准备在日记本上记录处理到哪个位置之时,突然被叫开了,当他回来后,发现张三请求没有记录下来,他会把张三请求再次处理一遍,这就会造成重复。

问题3:不重复(Exactly Once)

重复一定会带来问题吗?不一定。

在幂等情况下,重复虽然会有浪费,但对结果没有影响。什么叫幂等:重复消费不对结果产生影响的操作叫做幂等。例如用户有一个操作 “查询余额”,该操作是一个只读操作,重复做不影响结果。对于非只读操作,例如注销用户这类操作,可以连续做两次。

但现实生活中大部分操作不是幂等的,例如存款、取款等,重复进行计算会对结果带来致命的影响。解决的方式是什么呢?柜员(A)需要把账本完成 + 日记本标记Shard中处理完成作为一个事物合并操作,并记录下来(CheckPoint)。

如果A暂时离开或永久离开,其他柜员只要使用相同的规范:记录中已操作则处理下一个即可,如果没有则重复做,过程中需要保证原子性。

CheckPoint可以将Shard 中的元素位置(或时间)作为Key,放入一个可以持久化的对象中。代表当前元素已经被处理完成。

业务挑战

以上三个概念解释完成后,原理并不复杂。但在现实世界中,规模的变化与不确定性会使得以上三个问题便得更复杂。例如:

  1. 遇到发工资日子,用户数会大涨
  2. 柜员(Clerk)毕竟不是机器人,他们需要休假,需要吃午饭
  3. 银行经理为了整体服务体验,需要加快柜员,以什么作为判断标准?Shard中处理速度?
  4. 柜员在交接过程中,能否非常容易地传递账本与记录?

现实中的一天

8点银行开门

只有一个Shard0,用户请求全部排在Shard0下,柜员A也正好可以处理

10点进入高峰期间

银行经理决定把10点后Shard0分裂成2个新Shard(Shard1,Shard2),并且给了如下规定,姓名是[A-W]用户到Shard1中排队,姓名是[X, Y, Z] 到Shard 2 中排队等待处理,为什么这两个Shard区间不均匀?因为用户的姓氏本身就是不均匀的,通过这种映射方式可以保证柜员处理的均衡。

10-12点请求消费状态:

柜员A处理2个Shard非常吃力,于是经理派出柜员B、C出厂。因为只有2个Shard,B开始接管A负责一个Shard,C处于闲置状态。

中午12点人越来越多

银行经理觉得Shard1下柜员A压力太大,因此从Shard1中分裂出(Shard3,Shard4)两个新的Shard,Shard3由柜员A处理、Shard4由柜员C处理。在12点后原来排在Shard 1中的请求,分别到Shard3,Shard4中。

12点后请求消费状态:

流量持续到下午4点后,开始逐渐减少

因此银行经理让柜员A、B休息,让C同事处理Shard2,Shard3,Shard4中的请求。并逐步将Shard2与Shard3合并成Shard5,最后将Shard5和Shard4合并成一个Shard,当处理完成Shard中所有请求后银行关门。

现实中的日志处理

上述过程可以抽象成日志处理的经典场景,如果要解决银行的业务需求,我们要提供弹性伸缩、并且灵活适配的日志基础框架,包括:

  1. 对Shard进行弹性伸缩,参考LogHub弹性伸缩(Merge/Split)
  2. 消费者上线与下线能够对Shard自动适配,过程中数据不丢失,参考[LogHub Consumer Library-协同消费组自动负载均衡] (https://help.aliyun.com/document_detail/28998.html)
  3. 过程中支持保序,参考LogHub支持保序写入和消费
  4. 过程中不重复(需要消费者配合)
  5. 观察到消费进度,以便合理调配计算资源,参考通过控制台查看协同消费组进度
  6. 支持更多渠道日志接入(对银行而言开通网上银行、手机银行、支票等渠道,可以接入更多的用户请求),参考LogHub多种数据接入方式

通过LogHub + LogHub Consumer Library 能够帮助你解决日志实时处理中的这些经典问题,只需把精力放在业务逻辑上,而不用去担心流量扩容、Failover等家常琐事,是不是很爽?

另外,Storm、Spark Streaming已经通过Consumer Library实现了对应的接口,欢迎试用。有兴趣的读者可以参考下日志服务的主页,以及日志处理圈子,里面有不少干货哦。

时间: 2024-09-30 01:49:45

《银行的一天》演示日志处理保序、不丢、不重的相关文章

日志服务新功能发布(1)--支持保序写入和消费

日志服务在上周新上线的版本,支持数据的保序写入和消费,shard的split和merge, server端consumer group的原生支持(除去对mysql的依赖),数据自动同步至oss等一些列新功能.本文主要介绍数据的保序写入和消费的功能. LogStore & Shard 关系 每个LogStore对应一类日志,对于同一个LogStore下的数据,所有处理逻辑相同(索引方式.导入odps.oss等配置) 每个LogStore由一个或多个shard组成,用于支持数据写入水平扩展 每个sh

分布式系统中的RPC请求经常出现乱序的情况 写一个算法来将一个乱序的序列保序输出

分布式系统中的RPC请求经常出现乱序的情况.  写一个算法来将一个乱序的序列保序输出.例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是:  1  2  3, 4, 5  6  7, 8, 9, 10 上述例子中,3到来的时候会发现4,5已经在了.因此将已经满足顺序的整个序列(3, 4, 5)输出为一行. 要求:  1. 写一个高效的算法完成上述功能,实现要尽可能的健壮.易于维护  2. 为该算法设计并实现单元测试 我的思路是:  假设输入

保序加密在海洋环境信息云存储密文检索系统中的应用研究

保序加密在海洋环境信息云存储密文检索系统中的应用研究 陈建翔 云计算因其经济.便利.高可扩展性等诸多优势已成为当今信息技术领域的热门话题,受到研究者的广泛关注和重视.安全性是限制云计算发展的重要因素,由于云存储在海洋云计算中占有重要地位,海洋环境信息的云存储系统中的安全问题成为海洋云计算研究的重要问题之一.本文在结合海洋环境信息的特点下研究保序加密在海洋环境信息云存储检索系统的应用,为海洋环境信息的云存储密文检索提供了一种可行方法. 保序加密在海洋环境信息云存储密文检索系统中的应用研究

Python 分析Nginx访问日志并保存到MySQL数据库实例_python

使用Python 分析Nginx access 日志,根据Nginx日志格式进行分割并存入MySQL数据库.一.Nginx access日志格式如下: 复制代码 代码如下: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_f

Logtail技术分享(一) : Polling + Inotify 组合下的日志保序采集方案

日志数据采集 提到数据分析,大部分人首先想到的都是Hadoop,流计算,API等数据加工的方式.如果从整个过程来看,数据分析其实包含了4个过程:采集,存储,计算和理解四个步骤. 采集:从各种产生数据的源头,将数据集中到存储系统.包括硬盘上的历史数据,用户网页的点击,传感器等等 存储:以各种适合计算的模式集中式存储数据,其中既包含大规模的存储系统(例如数仓),也有例如临时的存储(例如Kafka类消息中间件) 计算:形态多种多样,但大部分计算完成后会将结果再放入存储 理解:利用机器学习.可视化.通知

遵循互联网架构“八荣八耻”,解析EWS高质量架构6个维度的20个能力

本文主要从最初的聚石塔容器服务EWS开始讲起,进而分享了EWS 高质量架构产品化的C2B方案和全渠道方案,着重说明了EWS的技术实现,包括EWS的总体架构以及EWS的功能实现等. 直播视频:点此进入 PDF下载:点此进入 以下是精彩内容整理:   聚石塔 聚石塔是阿里的电商云平台,聚石塔主要向商家提供电商云的支撑,能够更方便的和阿里做技术上和系统上的对接,所有的ISV和服务商开发的系统都部署在聚石塔上.今年整个零售平台提供了16字目标:聚焦体验.升级消费.赋能商家.繁荣生态.聚石塔扮演的是技术赋

阿里封神-大数据处理技术漫谈

以前一篇博客,从宏观描述了云梯1当时整体生态,年底了,笔者再梳理下软件栈,主要以开源软件为主,闭源不谈.大数据发展至今,开源软件层出不穷,也去解决了不同的问题,笔者试图去弄清楚这些,分门别类,后面也可以参照下.由于笔者知识面有限,难免会出现一些偏颇,不全,不正确,还请指正.后面也会有很多新的软件出现,一段时间后,软件栈也会变化的. 典型架构 很多的场景都是如上的,有web(包括无线.以前CS的模式.现在的BS模式等).DB.cache.数据分析我就用了Hadoop了(代名词,或者泛指数据仓库了)

银行想方设法整治银保顽疾

银保人员衣着不能混淆 不许卖给60岁以上老人 本报讯(见习记者 程思思 实习生 李俊婧 管静 何秧秧) 保险人员衣着不能与银行员工一样,禁止向年龄超过60岁的老人销售保险--昨日,记者从武汉地区部分银行了解到,为了规范银保销售行为,先后开始堵漏设防. "近期,总行下发了有关规范银保销售行为的文件,将以前的措施更加细化."工行湖北省分行营业部个金部总经理程进告诉记者,目前该行规定保险公司人员和银行工作人员必须穿不一样的制服,佩戴保险公司的胸牌.保险公司人员不能够单独销售银保产品,不能够充

ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自:http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志.应用程序日志和安全日志.系统运维和开发人员可以通过日志了解服务器软硬件信息.检查配置过程中的错误及错误发生的原因.经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误. 通常,日志被分散的储存不同的设备上.如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志.这样