滴滴开源 Levin:数据闪电加载方案

逻辑玄铁探
• 阅读 2431

1.背景

互联网某些业务场景下,我们常会遇到这种情况:服务启动需要加载大量数据到内存,数据规模达数十G,数据更新频率较低(天级、小时级、分钟级),使用方式为静态查询。如业务订单数据、线下挖掘的策略规则,地图路网数据等。而在线服务基于稳定性考虑通常至少加载双版本数据,服务启动通常需要数分钟之久。暴露的问题包括服务上线旷日持久,人力成本高;需求排队无法快速迭代,时间成本高;回滚速度慢,由于要加载大量数据故障实例无法快速恢复造成稳定性隐患。

如同闪电(Levin)一般快速加载启动是根治这类问题的灵丹妙药。Levin是针对上述低频更新、静态使用、大规模数据的快速加载方案,高效托管大规模静态数据,加速大内存服务冷启动和热加载。

2.原理

服务启动唯快不破,但是在单纯的服务变更场景中(比如上线、回滚、故障恢复)虽然并不涉及任何数据变更,服务进程重启导致堆和栈内存数据都会随之消亡,启动后需要重新加载数据。那么数据能不能在进程间传递复用呢?最高效的进程间数据传递方式就是共享内存,共享内存可以突破进程生命周期实现跨进程重用,并且具有内存对象访问效率和充足的可用地址空间(下图Memory Mapping Area),鱼(启动速度)与熊掌(查询效率)可以兼得。

滴滴开源 Levin:数据闪电加载方案

再考虑数据更新场景,通常指数据版本切换,此时磁盘数据读取在所难免,那么从数十G的数据文件到内存数据对象(通常为STL容器),是否存在更高效的转换方式?思考如果直接离线编译出数据对象内存布局写入二进制文件,在线服务启动时进行一次性共享内存分配和IO读取,可以进一步提高加载效率。

在确定了使用共享内存和容器数据离线编译之后,关键的问题来了,如何将容器放入共享内存?最大的障碍是指针和容器内存不连续性。Levin的武器是降维:容器对象内存布局一维化,在一维世界中只需首地址加长度就可以表达、读取和复制整个容器对象。由于同一块共享内存会映射到不同进程的不同虚拟地址,使用偏移量代替容器中的指针,实现地址无关的容器。

我们也对造好的轮子(Boost interprocess容器)进行调研,发现其基线测试性能表现不佳:最常用的vector/hashmap查询效率较标准容器慢10%~20%左右。最终Levin选择了自定义共享内存容器,并在数据静态使用方式的前提下做了一系列优化,具备简单易用、效率高、性能好、内存省的优点。并实现了工程化应用落地不可或缺的功能:如共享容器内存校验、版本管理。

3.功能与特性

▍STL-like共享内存容器

支持托管在共享内存片段上的容器,包括常用容器vector、set、map、hashset、hashmap等。并支持使用适配、组合、特化等手段自定义共享内存容器。
基线测试表明Levin容器查询性能较标准容器有所提升,内存使用效率优势明显(详见benchmark)

Levin2.jpg滴滴开源 Levin:数据闪电加载方案

▍离线数据编译

高效使用数据是在线服务的目标,数据规范化是构建复杂系统的前提。
很多以数据为核心的系统都会将数据流程划分为离线编译和在线加载,其中离线数据编译是数据高效转换的重要一环,利用离线单节点把数据转换为可以方便使用的格式,省掉在线服务多节点重复的转换和构建工作。
Levin支持离线数据编译功能,将原始数据编译为进程可直接读入的共享容器对象内存布局二进制文件,为在线服务提供更加高效的数据服务。

▍在线数据加载

加载离线阶段编译产出的数据文件至命名共享内存区域,支持共享容器对象申请、校验、加载、释放。
Levin在线数据加载进行一次性共享内存分配和读取,省掉构建过程大量brk/mmap内存分配系统调用,减少IO次数,为在线服务数据加载进一步提速。下图是以上介绍的数据使用流程,推荐这种方式。

Levin3.jpg滴滴开源 Levin:数据闪电加载方案

▍管理模块

用户大量使用共享容器时,共享容器使用情况全景不透明,逐个释放容易遗漏,服务出现异常等情况下会导致无用数据驻留内存空间,浪费节点内存资源。
Levin提供管理模块,支持共享容器以集合(group)的方式进行管理,相同生命周期的共享容器可交由同一管理模块实例托管,进行统一的创建、加载,释放。管理模块还支持共享容器全局搜索功能。支持安全释放、清理功能,避免容器数据异常销毁或无用容器驻留系统。支持可定制的数据文件校验方式,降低文件校验耗时。

▍版本切换

使用Levin管理模块对同版本容器数据进行group管理,卸载特定版本时可安全、统一释放相应的共享容器集合,完美支撑用户数据版本热切换需求实现。

4.内部实践

Levin内部应用实践效果:落地服务冷启动和热加载耗时均由分钟级降至秒级。内存用量方面优化明显,Levin容器静态数据转而由共享内存托管,与服务session动态数据分离。观察数据版本切换场景,磁盘IO次数大幅降低,切换导致的cpu抖动也明显缓解。以上,本文开头提到的人力、时间成本浪费和稳定性隐患问题迎刃而解。
闪电加载,你值得拥有!Getting Started

5.项目页面

GitHub: https://github.com/didi/levin
Documentation: https://github.com/didi/levin...
欢迎Star,欢迎Issue。

同时也欢迎大家扫描下方的二维码关注滴滴技术公众号,我们会及时发布最新的开源信息和技术资讯!
滴滴技术公众号二维码.jpg

点赞
收藏
评论区
推荐文章
Stella981 Stella981
4年前
Hibernate之二级缓存
一:二级缓存简介为什么需要缓存:      查询大量数据时更快,拉高程序的性能什么样的数据需要缓存:      很少被修改或根本不改的数据数据字典业务场景比如:耗时较高的统计分析sql、电话账单查询sql等关系型数据库:数据与数据之间存在关系(联系)的数据库mysql/Oracle
Stella981 Stella981
4年前
2019年初,一次Confluence迁移升级历程
AtlassianConfluence从5.7.1升级到6.14.1背景随着时间的推移用户量不断增长数据量也越来越大Confluence最初安装使用的是内存数据库由于这个技术债务所需的资源(尤其是内存)越来越大服务启动所需JVM需求不断增长:4G—8G—12G曾出现因JVM不足导致系统慢或重启失
Stella981 Stella981
4年前
Go实现基于WebSocket的弹幕服务
拉模式和推模式拉模式1、数据更新频率低,则大多数请求是无效的2、在线用户量多,则服务端的查询负载高3、定时轮询拉取,实时性低推模式1、仅在数据更新时才需要推送2、需要维护大量的在线长连接3、数据更新后可以立即推送基于webSocket推送1、浏览器支持的socket编
Wesley13 Wesley13
4年前
MySQL 快速创建千万级测试数据
备注:此文章的数据量在100W,如果想要千万级,调大数量即可,但是不要大量使用rand()或者uuid()会导致性能下降背景在进行查询操作的性能测试或者sql优化时,我们经常需要在线下环境构建大量的基础数据供我们测试,模拟线上的真实环境。废话,总不能让我去线上去测试吧,会被DBA砍死的创建测试数据的方式
云内GSLB技术及应用场景
云业务容灾建设节奏一般是同城双活—异地双活—两地三中心(同城双活异地多活),因为要解决的问题的复杂度和难度也是在逐步上升的,不可能一蹴而就。gslb可以实现两地三中心容灾,这时应用在多数据中心的情况下,业务需要分布式部署,无论哪个数据中心都可以独立承担业务,数据中心内通过服务器负载均衡(lb)进行数据中心内的业务负载,gslb是通过dns给lb做负载均衡,配合健康检查实现业务的故障切换,数据中心切换,一些算法如静态就近性可以就近访问加速等。
记录一次RPC服务有损上线的分析过程
作者:京东零售郭宏宇1.问题背景某应用在启动完提供JSF服务后,短时间内出现了大量的空指针异常。分析日志,发现是服务依赖的藏经阁配置数据未加载完成导致。即所谓的有损上线或者是直接发布,当\\\\应用启动时,service还没加载完,就开始对外提供服务,导致
记录一次RPC服务有损上线的分析过程
作者:京东零售郭宏宇1.问题背景某应用在启动完提供JSF服务后,短时间内出现了大量的空指针异常。分析日志,发现是服务依赖的藏经阁配置数据未加载完成导致。即所谓的有损上线或者是直接发布,当\\\\应用启动时,service还没加载完,就开始对外提供服务,导致
taskbuilder taskbuilder
1年前
TaskBuilder触发前端组件请求后台服务的常见事件
当以下事件发生时,可能会触发相关前端组件向后台服务发起请求:4.3.1页面加载时这种情况主要用于数据查询,在前端页面加载完毕后(页面静态内容渲染完毕),会自动判断页面里的每个前端组件是否设置了数据查询操作,如果设置了,则自动请求相应的后台服务进行数据查询,
不是海碗 不是海碗
2年前
一文学会分钟级降水预报接口使用,实时获取准确的天气降水信息
天气对我们的日常生活和各行各业都有重要影响。特别是对于需要关注降水情况的行业,如农业、城市排水系统、交通管理等,准确的分钟级降水预报数据尤为关键。分钟级降水预报API接口的出现,为开发者和应用程序提供了便捷和可靠的方式来获取这些重要的天气数据。
后端服务之应用预热 | 京东云技术团队
一背景C端服务应用升级和重启,导致耗时瞬时抖动,业务超时,应用监控报警,上游感知明显,导致用户体验变差。二应用升级重启导致抖动的原因1C端服务应用升级和重启的冷启动阶段,它需要重新加载和初始化各种资源,例如数据库连接、缓存数据等,导致耗时瞬时飙升。2应用重
记录一次RPC服务有损上线的分析过程
1\.问题背景某应用在启动完提供JSF服务后,短时间内出现了大量的空指针异常。分析日志,发现是服务依赖的藏经阁配置数据未加载完成导致。即所谓的有损上线或者是直接发布,当应用启动时,service还没加载完,就开始对外提供服务,导致失败调用。关键代码如下数据