eBay 的员工 Venkatesh Ramaswamy 于 2017 年 1 月发布了一篇文案,文案发布在 eBay 技术博客上,文案重点讲了针对购物车缓存数据丢失状况,eBay 思考的三种处理方法,以及最后采用的处理方法。背景
eBay 的购物车信息存储依赖于两个区别的数据存储介质,MongoDB 存储用户完整的购物车信息,Oracle 仅存储购物车的大致信息,然则能够经过关键信息查询所有的购物车信息。在 eBay 的这套系统里,MongoDB 更加多被用来充当“缓存”,Oracle 数据库做为存储副本。倘若数据在 MongoDB 里面找不到了,服务会从 Oracle 里面重新抽取(恢复)数据,而后重新计算用户的购物车。
所有的购物车数据都是 JSON 格式的,JSON 数据在 Oracle 里被存储在 BLOB 格式的字段里。这些 Oracle 里面的数据只能被用于 OLTP 交易。
这篇文案并不是讨论数据库技术的选取(Oracle vs MongoDB,或其他数据),而是期盼能够让大众在巨量拜访系统(每日上百万次调用)中找到技术债,理解怎样处理问题。
问题描述
2016 年秋天起始,购物车服务显现了缓存层丢失数据的状况,同期,运维团队报告 MongoDB 的备份机制多次显现失败(MongoDB 运行在主从模式)。eBay 的这个服务已然运行了 5 年时间,始终无显现问题,无做过任何架构调节和大规模代码改变,需要尽快找到原由和防治办法。针对实质问题进行反复检测,发掘 MongoDB 的 oplog(实时性需求极高的写日志记录)正在达到网络 I/O 限制。每一次的数据丢失,都会触发守护办法(再次从 Oracle 读取数据后重复计算),并进一步加长用户的等待时间。
处理方法
在咱们具体讨论特定的处理方法前,咱们期盼去尽可能多地讨论处理方法。例如,一旦备份机制无启用,是不是能够经过隐匿有些副本方式让系统能够正常运行,而不要在系统尤其繁忙的时候去尝试重新备份。咱们能够尝试超机会制和周期性副本方式,然则这些方式并不会导致咱们本文说的问题出现。
方法一:切片(MongoDB)
团队成员提出对 JSON 数据进行切分,即对原先存储在 MongoDB 里的原子化的购物车信息(一个 JSON 字符串),切分为多个字符串,这般做的好处是能够减少单一 MongoDB 中心节点的写入次数和网络开销。
针对数据切分后的相关方式,远比数据切分、负载平衡繁杂,因此呢,第 1 种方法的选取会引入其他技术难点,需要咱们自己能够寻找被切分后的数据的相关性,这便是为何 eBay 放弃了这个方法。
方法二:有选取的写入
运用 MongoDB 的 set 命令,只针对当特定值出现更改后,才起步写入操作。这种方式理论上亦是可行的。
然则倘若你真正思虑一下,这种做法无从基本上保证减少 oplogs 写入次数,然则它很有可能会导致全部文档的更新。
认识一下 MongoDB 的 Set 操作模式。Set 操作能够用于运用特定值替换字段值:
{$Set{:,…}}
假如你思虑一下描述制品的文档如下所示:
{
针对满足 _id 等于 100 的文档,执行 set 操作更新 quantity 字段、details 字段和 tags 字段的值。
db.products.update( {_id:100}, {$set:
以上这个操作替换 quantity 的值为 500,details 字段的值为一个新的嵌入式文档,tags 值为一个数组。
方法三:压缩传输数据
思虑到需要尽快处理问题,因此需要尽可能避免重写业务规律,压缩方式看起来是比较好的一中了。减少进入 MongoDB 的 Master 节点的数据量,这般能够减少写入 oplog 的数据规模。然则,这种方式会将 JSON 字符串转变为二进制文案,操作时亦需要解压缩。
常用的压缩算法重点有:deflate、gzip、bzip2、lzo、snappy 等。差别如下所示:
deflate、gzip 都是基于 LZ77 算法与哈夫曼编码的无损数据压缩算法,gzip 只是在 deflate 格式上增多了文件头和文件尾;
bzip2 是 Julian Seward 研发并根据自由软件 / 开源软件协议发布的数据压缩算法,Apache 的 Commons-compress 库中进行了实现;
LZO 致力于解压速度,并且该算法亦是无损算法;
LZ4 是一种无损数据压缩算法,着重于压缩和解压缩速度;
Snappy 是 Google 基于 LZ77 的思路用 C++ 语言编写的快速数据压缩与解压程序库,2011 年开源。它的目的并非最大程度地压缩,而是针对最快速度和恰当的压缩率。
目的和思虑
在咱们起始做这一功能性测试之前,咱们需要知道几个目的。
准许购物车被压缩并持久化到 MongoDB(数据不会有改变)。
准许压缩编码方式的选取,支持采用一种编码方式读取,另一种编码方式写入。
准许读到老的、新的、中间状态的购物车信息,新老前后能够互相兼容。
压缩和解压缩的操作能够同期进行。
保证无针对 MongoDB 数据库的实时 JSON 数据检索查找请求。
JSON 字符串例子
这是老的 JSON 字符串:
{ "_id" : ObjectId("560ae017a054fc715524e27a"), "user" : "9999999999",
这是压缩之后的 JSON 字符串:
{ "_id" : ObjectId("560ae017a054fc715524e27a"), "user" : "9999999999",
测试结果
经过运用相同的购物车数据进行测试,观察 CPU 或 I/O 状况,数据如图所示:
结论
oplog 的写入速率,从 150GB/ 小时下降为大约 11GB/ 小时,下降了 1300%!文档的平均对象体积从 32KB 下降为 5KB,600% 的下降。另外,服务的响应时间亦有所改善。数据如图所示:
下面这张图表示的是 MongoDB 的 Ops Manager UI 工具信息,尤其标注了压缩和解压缩数据的耗时,以及文档的平均对象体积的下降数据。
最后,针对生产环境下的随机一小时数据压缩,eBay 团队亦收集了有些指标图,用于更加多的深入观察。
End.
源自:公众号“大数据杂谈”
运行人员:中国统计网博主(微X号:itongjilove)
博客ID:中国统计网
中国统计网,是国内最早的大数据学习网站,公众号:中国统计网
http://www.itongji.cn