文章目录

  • 1. 前言
  • 2. 论文结构
    • 2.1 海啸 问题
    • 2.2 泄洪 问题
    • 2.3 洋流 问题
  • 3. X-engine架构
    • 3.1 读路径优化 概览
    • 3.2 写路径优化概览
    • 3.3 Flush和Compaction
  • 4. X-engine 优化细节
    • 4.1 读路径上的优化
      • 4.1.1 Extent的设计
      • 4.1.2 Cache的优化
      • 4.1.3 多版本元数据索引的设计 -- Extent复用
      • 4.1.4 Cache的增量替换
    • 4.2 写路径上的优化
      • 4.2.1 多版本memtable的实现
      • 4.2.2 异步写事务
      • 4.2.3 多级流水线
    • 4.3 Flush和Compaction
      • 4.3.1 快速刷新L0中的warm extents
      • 4.3.2 Compaction 加速

1. 前言

论文原地址
X-Engine: An Optimized Storage Engine for Large-scale E-commerce Transaction Processing
中文介绍
x-engine最佳实践

因为本篇论文本身就是阿里重写了LSM架构,在原有rocksdb实现的基础上做了非常多的优化,这里如果对rocksdb整体实现没有足够的了解,就体会不到X-engine优化思想的精妙之处。
如果想要详细了解rocksdb的各个模块的实现,可以参考如下几篇文章:

1. Rocksdb 写流程,读流程,WAL文件,MANIFEST文件,ColumnFamily,Memtable,SST文件原理详解
2. Rocksdb compaction源码剖析 (一): SST文件详细格式解析
3. Rocksdb compaction源码剖析 (二):整体实现概览
4. Rocksdb WAL 实现详解
5. Rocksdb DeleteRange实现原理
6. Rocksdb 性能分析和调试的一些思路和方法
7. Rocksdb 事务和隔离级别的实现

ps: 当然有基础的伙伴可以进入正题,一起讨论哈
没有基础的伙伴可能需要简单概览一遍,会花费较多时间,不过有趣也很枯燥。。。。哈哈哈

不得不说一群大佬聚集在一起还是能够产生非常优秀的思想和产品的,将一个 数据引擎做到极致,每一个优化细节都精心雕琢,还是能够吐出非常可观的性能和延时指标的。

即使在如今LSM 读上一直被人诟病的情况下,X-engine逆流而上拿出了属于自己的优化策略,从而实现了X-engine写性能优于innodb,而读性能仅仅比innodb差一点的性能,这在LSM的引擎架构下实属难得。

X-engine毕竟是自研的,而且作为Polordb-X的存储引擎,必然是要走收费路线了,底层代码肯定是看不到的,不过整个基于LSM 优化实现的思想已经在论文中一一体现,非常详细,想必也能为自己在现有rocksdb引擎的基础延伸一些思考。

2. 论文结构

整个论文所描述的阿里云想要解决的问题 被cheng 博士归纳为三个问题(不得不说学术大佬的抽象思维能力真是强):

  • 海啸
  • 泄洪
  • 洋流

论文后续的优化细节描述以及测试和展望 都是围绕如何更好得解决以上三个问题展开的。

接下来简单为大家描述一下cheng 博士归纳这三个问题的背景以及每个 问题对应那一些具体业务上的痛点,而阿里庞大用户基数以及数据量的支撑下所体现出来的问题便能够暴露出一套存储系统在各个纬度上设计的不足。

1. 淘宝天猫 用户交易数据
在阿里 淘宝和天猫 都会存储用户交易数据,我们的这一些数据在阿里云服务器上是需要永久保存的,从而提供历史记录让用户查询,交易集群面临如下问题:

  • 数据条目过万亿,磁盘容量达到TB级别
  • 在大促销时会面临巨大的冷热数据交替访问的压力

而想要性能可以通过拆分数据库,将一部分数据迁移到新的集群,理论上是能够实现容量和性能的无限扩展。但是集群数量的增大也为整个集群的运维成本带来巨大的复杂度,而且存储成本仍然在不断增加。
为了降低存储成本,并提升促销时的性能 ,这一些核心业务引入了X-engine。

2. 钉钉 聊天记录信息库
同样,钉钉作为中国领先的企业办公通信软件,需要实现聊天记录的永久保存,并且提供多端漫游功能。
随着用户的爆发式增大,达到亿级别。整个系统的存储成本代价较大,如果在不影响现有innodb二级索引以及事务处理功能的前提小进一步降低存储成本,引入了X-engine。

3. 阿里图片信息库
阿里巴巴集团图片空间是淘宝智能图片中心面向商家提供的免费图片存储管理服务,本身淘宝天猫累积的商家图片信息已经非常庞大, 随着双十一和双十二购物节前后,商家又会大量上架新的商品图片,图片信息数据会爆发式增长。

图片的索引信息是通过URL的,非常适合前缀压缩(rocksdb)。为了进一步节约存储成本,保证请求时延 、吞吐和innodb没有太大差异的前提下,阿里引入了X-engine来作为图片信息数据库的存储引擎。

可以看到X-engine是为特定的业务场景设计的,能够将自己的优势完全体现出来。即使这样,在阿里庞大的数据量支撑下,X-engine也创造了巨大的收益。

回到cheng博士归纳的三个问题:海啸、泄洪、洋流

2.1 海啸 问题

阿里巴巴的淘宝和天猫有全球用户都会参与的购物节,像是双十一,双十二这样的。
这一些购物节在会在午夜零点开始,一般会持续一天时间。而对于午夜零点那一刻有,整个系统的数据会以百倍千倍的的压力奔向服务器,同时衍生的数量更为庞大的事务workload 更是像人类的海啸一样拍向海岸。

如上图中,论文展示的整个系统的吞吐在双十一零点时的表现,红色的曲线代表的是系统的吞吐,高于平时的122倍。
而蓝色的曲线代表的是请求时延情况,阿里的x-engine即使流量暴增的情况下仍然保持较为稳定的时延。

也就是在海啸场景下,引擎的海岸要足够坚硬高大,承接住这样的压力。

2.2 泄洪 问题

同样是在海啸场景下,我们要将关注重心转移到引擎层的处理过程。引擎需要有快速搬迁数据的能力,快速得将数据从主存中搬迁到底层持久化存储设备中。从而将高速的主存空间空出来接受上层海量并发的事务处理。

即使如今我们主存的容量仍然在稳定得增加,但是在面对海量的写入、更新操作的过程中主存容量还是捉襟见肘。所以,这个时候利用已有的存储设备RAM, SSD, HDD 来搭建一套按照数据热度分层存储的系统达到“泄洪”的目的。
这也就是X-engine冷热分离的思想,按照数据热点高低,将数据分布在速度比较快的RAM,比较高速的持久化设备SSD以及最慢的,保存热度最低数据的HDD。同时一些新的内存技术,像是NVM也能够应用到整个分层的过程。

在此x-engine 所做的存储引擎架构选型就抛弃了传统的B树结构,采用天然适配冷热分离的存储架构的LSM 结构。而且LSM拥有常驻内存的数据结构(memtable)能够以追加写(append-only)方式快速插入,再加上分层常驻于磁盘的结构就为泄洪问题的解决在软件层面做了技术上的架构铺垫。

2.3 洋流 问题

对于大多数数据库场景,热点数据会被持续访问一段时间。而在电商促销场景下的workload,会出现冷热数据的交替变化(我们买一件促销衣服,而下面又会推荐对应的鞋子,衣服刚开始促销时是热点数据,鞋子过了一会从热点数据变为冷数据),这里的冷热交替是指数据加载到高速设备上,又被迅速泄洪到底层低热度设备。

如果将数据库的cache(存储热度最高的设备RAM)看作海面,下层持久化的数据库看作深海,那么这样的冷热交替过程就像是洋流一样将深海冷的水流带到海面,将海面温度高的水带入到深海。

所以x-engine在这样的场景下需要尽可能快得完成深水的上升,并快速得将他们缓存到高速设备(cache)。

通过以上X-engine论文中形象概括的三个问题,整个业务痛点就非常清晰了,而目标定下来,接下来就是整个解决过程了。

3. X-engine架构


如上图 是引擎中对x-engine整体架构的描述。X-engine的定位除了之前部分也描述一部分也是为了处理OLTP类型的数据(在线事务处理 – 电商促销平台),主要是解决三个主体问题,所以这里从架构设计上也能看出来。整体的优化相比于传统LSM 架构主要体现在三个方面:读路径,写路径Flush和Compaction

具体的优化点 论文中已经整理出来一个表格如下:

3.1 读路径优化 概览

读路径是指 从存储中将读记录取出来返回给客户端 这一段路径。传统的LSM 在读性能上并不友好,因为它要先从memtable中读,memtable没有则会去底层LSM 中一层一层去查找,最为耗时的情况是从最后一层读到数据但是发现这个key并不存在。

Rocksdb针对以上读场景已有的优化是

  • MANIFEST (这个文件保存的是整个db在一段时间内的快照,有SST文件更新,创建,删除都会将SST文件相关的信息更新到这个文件中) 中会保存所有的sst文件的start-end key,然后查找时是需要确定key所属文件包含的key的范围。
  • BloomFilter 存放在blockcache内存中 ,用来百分百判断一个key不存在,概率性的判断一个key存在。

X-engine在针对key的点查 性能行进一步优化(因为电商平台促销时会产生大量的点查事务)。这里是针对x-engein 设计的有序字节表 extent的优化,维护一个 metadata index 结构用来索引extents和memtable。将多个metable index存放在cache中,查找的时候只需要通过cache 中的 metaindex快速索引到具体的extent 即可。

同时也做了一个增量的接口来对cache中的过时数据 进行高效的替换(我们知道compaction的过程会不断的生成删除sst文件,这一些更新的sst文件中的datablock记录也会被从blockcache中清理掉)来减少compaction过程中对blockcache中不必要替换的key进行更新(仅仅更新了一个datablock中的几个key,却要将整个datablock替换掉)。

这里仅仅是一个整体优化的概述,论文会在后续的细节描述部分进一步讨论。

3.2 写路径优化概览

写路径除了包括物理设备的IO,还有引擎层面的一些组件的插入和更新。

写请求会先写入redo logs(类似于rocksdb 的wal),完成之后会写入active memtable,达到阈值之后active memtable被标记为 只读 ,变为immutable memtable进行flush,同时创建一个空的active memtable继续快速接受请求。

X-engine 为了平衡IO的高延时(写WAL)和memtable写入的低延时,做了多级流水线,每一个线程可以处理任何一个阶段的写wal,在事务请求足够大的时候几乎能够将整个写wal和写memtable并行起来,提升了整个写入的吞吐。

3.3 Flush和Compaction

这里之所以两个机制的优化放在一块,因为他们都是异步执行的,同时也都是为了生成新的sst文件。Flush是将immutable memtable中的数据写入到L0形成sst文件。Compaction是对可能重叠的SST 文件中的key进行去重,也是为了清理delete ,多次put ,以及merge操作的key。

Compaction会存在于LSM中的不同层,挑选Ln的多个sst文件,再加上Ln+1层与上层重叠的key的sst文件,一起读到内存中作为一次compaction进行合并,将最终合并的结果再写入到新的SST文件之中。
这个过程会消耗比较多的CPU和IO,同时有较多的写放大问题,可能存在一个key反复被compaction了多次即使这个key的数据最终还是和原来一摸一样。

X-engine为了优化以上compaction和flush过程中的问题,做了如下几个方面的优化

  • 优化了memtable flush到L0的过程
  • 精细管理extent达到数据复用的目的,来降低需要被merge的extents数量
  • 通过异步IO 来对重叠的extents 进行合并
  • 解藕compaction到FPGA降低CPU 的消耗

4. X-engine 优化细节

X-engine 这里将针对事务的优化处理放到了第一个描述的位置,这里可能事务的优化对整体引擎的吞吐提升巨大,值得提前让读者体验。

X-engine通过MVCC(多版本并发控制)和2PL(两阶段锁)来实现对应的隔离级别: SI(snapshot Isolation)和RC(read commited)。 这两个级别其实也是rocksdb支持的隔离级别,关于这两个隔离级别的细节描述可以回到文章开头,有一篇关于rocksdb事务隔离级别的实现介绍,简单了解一下。

不同版本(rocksdb中的LSN)相同的user key会被自动增加的ID隔离。每一个输入到X-engine的事务读的时候也仅仅只能看到它之前的LSN,每一个LSN都可以作为自己的snapshot功能。每一个写入的事务也都会增加一个行锁(row lock)来比避免事务之间的写冲突。

整体优化后的 事务处理架构如下:

如上架构中,整个事务的处理由两部分组成(左侧部分):Read/Write 阶段 和 Commit 阶段。
所有的读请求都会通过read phase再进入读路径。在这个阶段,读请求会被当作一个事务 插入/更新 到事务缓冲区之中;接下来进入commit 阶段,任务继续从事务缓冲区中进行调度,将请求写入到分布式的write 队列中。最后由多级流水线 对后续的数据请求写入redo log和 插入到LSM中进行 并发调度。

4.1 读路径上的优化

4.1.1 Extent的设计

论文中写介绍了X-engine 设计的底层存储结构 – extent (类似与rocksdb的sst)

extent 和sst一样,主体还是由多个datablock组成,每个datablock包含具体的key-value数据,还有一个index block,用了索引当前extent 中的多个 datablock 结束key的位置,用于加速查找。

和sst差异的地方就是多了一个Schema data。这个数据区域为了支持上层的DDL语言,来加速电商平台中频繁变更数据库schema信息的场景,这个数据区域的设计对提升电商平台的数据库按主键查找、插入等依赖schema信息的请求性能 有非常巨大的提升。

整个extent 被设计为2MB的大小,这个2M的来源是经过不断测后续compaction中的extents复用功能 以及 cache替换 的优化 得到的最优的大小。

4.1.2 Cache的优化

接下来就是读路径上的具体优化了,首先看看cache的优化:

row cache的设计主要用来加速点查性能。row cache使用LRU 作为数据页的替换策略,这里不会关心具体的数据区域是否存在于LSM中。所以在LSM的最大层中的冷数据也可以被缓存到row cache中,这样能够加速冷数据的访问。此外点查过程中没有从memtable中找到,那么这个key最后 会被缓存到row cahce中,下次查找只需要O(1)的时间。
有一个问题是row cache对随机key场景并不友好,别缓存的key不一定经常访问。

在电商平台中,由于计算机系统的局部性原理,最新的请求大概率是会被继续访问的,所以row cache 尽可能保存最新的请求。为了实现这个功能,这里会在memtable flush时候将最新的请求更新到row cache中,强行将旧的请求淘汰掉。

block cache中主要缓存 以data block为单位的数据。保存row cache中淘汰的数据来降低cache miss,或者加速range 查找。其中table cache只要保存extent的元数据信息来定位具体的extent的位置,当extend加载到tablecache之中后会构造对应的bloom filter ,加速对不存在的key的过滤。如果key存在,则通过block cache缓存的index block查找对应的datablock数据。

整个cache的设计还是为了加速热点数据的访问,多级cache 为了降低cache -misses的效果。可能整体 的cache管理变得复杂多变,但是相比于读路径走一次IO的开销,这一些CPU计算的耗时就微不足道了,还是有可以借鉴的地方的。

4.1.3 多版本元数据索引的设计 – Extent复用

接下来介绍了多版本元数据索引的管理方式,设计如下图:

LSM-tree 中的subtable 会有一个与它相关联的metadata index,当有一些改动落到了当前metadata index所关联的key-value范围内时,会为这个改动生成一个新的metaSnapshot,并将这个snapshot插入到与它相关联的level之中(这个过程是通过Copy on write 机制来做的)而不需要更改其他的metaSnapshot的链接。

如上图,extenti 是属于level0层,而且被缓存到了blockcache当中。当compaction 过程中需要完全复用这个extent的时候,一个新的MetaSnapshot (v+1) 会通过metaSnapshot (v) 重新生成,并且连接到compaction的输出层level1。这里有一个相比于原本rocksdb 的 compaction的实现优化之处是当前的输出操作并不需要真正将extenti 从level0移动到level1,而是变更MetaLevel1的指针,指向Extenti即可。

所以这个通过MetaIndex管理的extent树 ,加上可复用的extent,能够极大得降低L0以上层之间Compaction的写放大问题

4.1.4 Cache的增量替换

还有一处读路径上的优化是Compaction合并文件过程中的Cache替换策略的优化。
LSM-tree原本的Compaction实现逻辑是在合并SST文件之后进行大量的cache替换,将block-cache中的参与过compaction输入的文件都替换为输出,即使cahce中存放的datablock输入输出前后并没有发生变化也会做一次cache 置换。这个过程会造成电商促销场景下的大量cache失效,降低读性能。

为了追踪这个问题,减少compaction过程中对未发生变化的datablock进行替换从而导致的cache-miss 比率,X-engine提出了增量替换block cache的策略。这里主要的实现过程是 Compaction过程仅仅对发生了合并且缓存在blockcache中的datablock进行替换,将老的datablock替换为合并后新的datablock,而不是针对整个extents所属的datablock进行全量替换。

4.2 写路径上的优化

X-engine描述了总体的写路径上的优化,报错从写入请求落到由LSM-tree管理的sub-table的过程,write task queue的设计 以及 优化最为彻底的多级流水线的实现细节。

4.2.1 多版本memtable的实现

X-engine 改造了memtable的数据结构,将skiplist改造为无锁skiplist 来加速插入和查找性能,这个改造在其他类似的系统中也实现了。

存在的问题是如果系统中存在数据热点,那么会经常插入单个相同的记录,只是会有多个版本,而用户只会读取最新的版本。而查找的过程则需要过滤掉大量的老版本的记录才能找到对应的记录。

X-engine为了解决上述多版本key的问题,追加一个新的版本,竖直连接到当前版本最后一个key的下面。

如上图,蓝色节点代表跳表。跳表中保存的是key的当前版本,而绿色节点之下则是key300的上一个版本。后续有关于key-300的其他版本,则采用单链表的头插法插入到key300跳表节点之下。

这样的设计能够降低查找key时 多个版本重复访问的消耗。

4.2.2 异步写事务

在常规的单线程单事务 处理写请求的存储引擎中(像innodb),都会在写的延时上耗时较多。一个用户线程完成一个事务从开始到结束的所有处理过程。如果用户不需要写请求的WAL(redo log)落盘,这个方法很容易实现写请求的并发控制,。如果用户需要写WAL,那么这样的单线程单事务的处理模式会导致线程长时间等待IO的情况,极为低效。

而X-engine这里有两个层面的优化:

  • 分开提交对应事务的写入
  • Batch 写

大体的实现方式和当前rocksdb的writer 类似,即多个线程并发写入,会为每一个线程创建一个writer。根据writer的创建时间 选择主writer ,其他线程的writer都会被标记为从writer,这个时候由主writer将所有请求的WAL数据汇总,batch write到底层,主writer写完之后所有的writer开始并发写事务,后续的事务处理就交给多级流水线来做了。

在这个场景下如果 上层的并发足够高,可以让后续的多级流水线完全并行起来,极大得提升吞吐。

4.2.3 多级流水线

在整个写路径上 会产生多个写入序列(生成事务,写WAL, 写memtable),当有并发线程的时候这一些序列可能会同时访问主存和磁盘,同时执行过程也伴随着大量的计算。所以很难通过计算来减少内存的访问和磁盘IO次数。

为了将计算和内存访问/磁盘IO 合理利用起来,X-engine实现了多级流水线的功能。如下图是整个四级流水线的形态:

  • Log-buffering 这一级主要是将线程从trasaction buffer中收集到的WAL 写入到log buffer中,并做一些CRC的校验。

    在这一级 有比较多的计算和内存访问(不会产生IO)

  • log-flushing 这一级会将log buffer中的数据写入到磁盘。并且会生成一个对应请求的lsn,这一级会产生IO

  • writing-memtabls 这里线程会并发将数据写入到active memtable中,仅仅会访问内存。

    当主存失效时 会从之前写入的log buffer (WAL)中进行数据重放,保证了memtable写入的crash recovery

  • Commits 最后一级,线程会并发提交事务的写入完成,并且会释放前面线程处理过程中所占用的内存和锁等资源。

X-engine为了合理的分配多级流水线处理过程中的线程资源,将第一和第二级的处理仅分配一个线程(写WAL需要先保证罗盘才行,单线程可以批处理),第三级之后都能够并发处理,则从第三级开始就分配了多个线程完成后续的操作。

4.3 Flush和Compaction

4.3.1 快速刷新L0中的warm extents

在X-engine之中通过flush过程将内存中的数据刷新到磁盘上,从而降低系统在大量的事务请求压力下产生的OOM的风险。X-engine中每一次flush操作都会将只读的memtable(immutable memtable)不经过排序,直接生成extents,并追加到L0之上。在电商平台中,刚写入的数据很可能会别再次读取到,所以x-engine这里将L0的作为warm层,即使L0的大小只占整个LSM的1%。

X-engine为了保证L0的热度,将L0中真正参与compaction的输出的extents文件保留在L0,并不会将他们下刷到L1,从而保证warm数据能够持续留在更高层。

4.3.2 Compaction 加速

Compaction的过程包含了非常耗时的merge操作,X-engine为了加速 compacion操作做了三种优化:

  • 数据复用
  • 异步IO
  • 卸载compaction到 FPGA

接下来一一看看X-engine的这三种针对compaction的优化,非常有借鉴意义。

数据复用 技术

这个我们在分析X-engine读路径上的 Cache增量替换的过程中有提到过这个优化,以如下图为例:

单个Extent的存储结构上面也描述过了,包括data block ,schema data, index block三部分。X-engine为了增加Extent的服用机会,让extent更加高效,将Extent的大小设置为了2M,每一个datablock的大小是16KB。

如果一个Extent的key的范围刚好属于 参与Compaction的key的范围,而这个extent并没有和其他参与compaction的extent 的key ran ge重叠,那么这个extent可以被当作可复用的extent。只需要为该Extent创建一个metadata index,更新到参与comoaction的metasnapshot 节点树之上。该extent不会产生一次IO,从而降低写放大。

举个例子:

这里有一次compaction,参与的层分别是L1和L2

L1中有三个extents 参与compaction: [1,35],[80,200], [210,280]

L2中有五个extents 参与: [1,30], [50,70]. [100,130], [150,170], [190,205]

如下是在不同场景下的 extent复用情况

  • L1的[210,280]和 L2的[50,70]能够被直接复用 – 在compaction的range范围内且和其他的extent没有重叠

  • L1的[1,35] 和 L2的[1,30]有重叠,但是只有L1的[1,25]datablock和L2的[1,10]data block有重叠,所以L1的data block [32,35] 能够被复用。

  • L1的[80,200]和L2的多个extent有重叠,它的第二个datablock和三个L2的extents有重叠。但是这个datablock的[135,180]区间并没有key,所以X-engine这里将这个datablock拆分成两个datablock: [106,135], [180,200],这两个datablock和L2的[100,130],[190,205]进行合并。这样L2的[150,170]这个datablock就能够被复用。

通过这样细粒度得管理,降低compaction过程中IO的次数,在事务密集型场景能够极大得降低compaction对上层吞吐的影响(内存操作相比于磁盘IO 肯定节约不少)。

异步IO技术

在extent写入到具体LSM的层的过程中主要分为三个阶段:

  • 从storage 层读入extents
  • 内存中进行合并
  • 将合并后的一个或者多个extent重新写入LSM之中

其中第一和第三阶段都是IO操作,第二阶段是内存操作。所以X-engine这里将异步IO的发力点放在了第一和第三阶段,将第一和第三阶段的IO操作变更为异步IO。第二个阶段是在第一阶段读入extents完成之后进行回掉的结果。

当并发进行Compaction的时候 第二个执行阶段会 会被隐藏,防止出现重复处理。(rocksdb在这里的处理逻辑是当前调度的compaction会对参与处理的sst文件进行标记,后续的compaction线程检测到该标记,便不会将该文件添加到compaction的处理之中)

FPGA offloading

这个技术是结合新硬件FPGA 将compaction offload到CPU上,从而降低compaction对CPU和影响,也进一步降低compaction对上层吞吐抖动的影响。

这里之所以选择compaction,也是因为Compacion本身是一个相对独立的操作,在两个连续的层之间处理extents。将这个过程单独通过FPGA以流处理的方式读入,再按照对应的extents格式由FPGA内核经过Cmodule写出。

关于Compaction on FPGA的细节可以参考论文

FPGA-Accelerated Compactions for LSM-based Key Value Store

到现在为止,基本的X-engine在LSM上的优化已经说的差不多了,大佬们的很多思想还是能够借鉴的。

论文的后续就是一些优化后的性能评估,评估的策略还是按照开头提出的三个电商促销平台的主体问题:

  • 海啸
  • 泄洪
  • 洋流

在三个问题下: 作为MySQL的一个引擎 进行不同workload的业务测试,引擎层面对比了innodb,rocksdb 两个单机引擎。后续的一些详细数据就不多介绍了,大家可以仔细看看论文中的第四节 Evaluation数据。

总的来说,x-engine 在电商促销场景下拥有不弱于innodb的读性能,优于innodb的写性能,能够在部分场景下比innodb节约62%的存储空间(钉钉历史消息库)。

LSM优化系列(五) -- 【SIGMOD‘19】X-engine 在电商场景下针对大规模事务处理的优化-- 强者恒强啊相关推荐

  1. 我用多线程进一步优化了亿级流量电商业务下的海量数据校对系统,性能再次提升了200%!!(全程干货,建议收藏)

    大家好,我是冰河~~ 在[精通高并发系列]的<我用多线程优化了亿级流量电商业务下的海量数据校对系统,性能直接提升了200%!!(全程干货,建议收藏)>一文中,我们主要使用了CountDow ...

  2. 【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 建模方案及代码实现

    相关信息 (1)建模思路 [2023 年第十三届 MathorCup 高校数学建模挑战赛]A 题 量子计算机在信用评分卡组合优化中的应用 详细建模过程解析及代码实现 [2023 年第十三届 Matho ...

  3. 社交电商怎么做?只需要五步,就可以做社交电商赚钱?

    移动互联网快速的发展下,越来越多的企业家朋友,开始重视社交电商这个领域,其实早在从2014年提出"新零售"这个概念之后,就有许多的朋友,有在观望的.注视的.忐忑的.没有方向的,直至 ...

  4. 【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 赛后总结之31页论文及代码

    相关信息 (1)建模思路 [2023 年第十三届 MathorCup 高校数学建模挑战赛]A 题 量子计算机在信用评分卡组合优化中的应用 详细建模过程解析及代码实现 [2023 年第十三届 Matho ...

  5. 2023MathorcupC题电商物流网络包裹应急调运与结构优化问题建模详解+模型代码(一)

    电商物流网络包裹应急调运与结构优化问题 第三次继续写数模文章和思路代码了,不知道上次美赛和国赛大家有没有认识我,没关系今年只要有数模比赛艾特我私信我,要是我有时间我一定免费出文章代码好吧!博主参与过十 ...

  6. 【Webpack 性能优化系列(6) - code splitting 】通过代码分割来获取更小的 bundle,优化资源加载

    webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(8) - PWA]使用渐进式网络应用程序为我们的项目添 ...

  7. 我用多线程优化了亿级流量电商业务下的海量数据校对系统,性能直接提升了200%!!(全程干货,建议收藏)

    大家好,我是冰河~~ 最近不少运营同事找到我说:咱们的数据校对系统越来越慢了,要过很久才会显示出校对结果,你能不能快速优化一下呢?我:好的,我先了解下业务啊. 注:全程干货,文章对你有点帮助的话,小伙 ...

  8. 未来五年,做淘宝电商不做好私域流量,将寸步难行!

    关键词:淘宝电商.私域运营.私域流量 使用行业:通用 这是个相对的概念,"私域"相对"公域".公域就是对所有企业品牌而言,大家集体共有的流量渠道,这其中有免费的 ...

  9. 19.亿级流量电商详情页系统实战---总结

    文章目录 1.亿级流量电商网站的商品详情页系统架构 2.redis企业级集群架构 3.多级缓存架构设计 4.数据库+缓存双写一致性解决方案 5.缓存维度化拆分解决方案 6.缓存命中率提升解决方案 7. ...

最新文章

  1. SAP MM 初阶之事务代码MIGO中采购退货的处理
  2. 魅族的android m l,Android M 外部存储剖析
  3. 每天一个linux命令(35):ln 命令
  4. AIX 系统的启动和关机
  5. 【git学习二】git基础之git管理本地项目
  6. matlab 角域重采样,matlab滤波技术与区域处理---区域滤波
  7. JMeter Listeners - Part 2: Listeners that Aggregate Data Samples
  8. python怎么播放本地录音_Python播放音频与录音
  9. YoloV5实战:手把手教物体检测
  10. java day52【综合案例day04】
  11. 宝塔面板SSpanel-v3-mod安装教程 搭建sspanel v3魔改前端
  12. shiro中的过滤器
  13. pbootcms模板忘记后台密码怎么办?
  14. JS获取今天是星期几
  15. 计算机网络嗅探实验,网络嗅探与欺骗实验
  16. 应用程序安装在sd卡还是内存选择及设置
  17. MySQL数据库优化-运维角度浅谈
  18. MATLAB下载遇到的问题:弹出DVD1并插入DVD2
  19. Kettle使用笔记
  20. 微信抢红包的方案_微信抢红包方法图文详解

热门文章

  1. python BGR 转换为 RGB
  2. AMBA APB学习记录(AMBA 2.0)
  3. 如何从Mac上卸载MacBooster 7?
  4. 现在做亚马逊测评容易吗?测评存在哪些问题?如何解决测评问题
  5. 与柯尼塞格达成合作后 恒大或将继续瞄准中高端新能源车
  6. php怎么给超链接设置样式,html中如何设置超链接的样式
  7. 富士施乐3065扫描教程_扫描打印论文,关于高效灵活——富士施乐DocuCentre-IV3065多功能打印一体机测试相关参考文献资料-免费论文范文...
  8. 树莓派3B+ 刷Nexmon 库
  9. Android 全面屏适配及判断是否为全面屏,全面屏手势和虚拟导航栏的判断
  10. 7-5 就不告诉你 (15 分) PTA 练习题满分答案