天使动漫,恭喜发财歌词,兴-果粒新闻,独立撰稿人喂你“食”新闻

大数据技能和运用体系现在已经在各个职业中发挥着巨大的作用,各式各样的开源技能也给大数据从业人员带来了很大的便当。Bitmap 作为一种大数据需求下发生的核算体系,有着核算速度快、信息密度高、支撑海量数据等许多优势。

美图具有海量用户数据,每天都有许多数据核算使命。而 Bitmap 技能能大幅度削减核算的开支,节约数据存储的本钱,尽管有不少公司做过 Bitmap 的相关测验,可是到现在为止还没有一个相对老练的分布式 Bitmap 开源运用,因而美图研制了自己的分布式 Bitmap 体系,运用于美图各个场景下的相关数据核算使命。

/ Bitmap简介 /

Bitmap 作为被各种结构广泛引证的一门技能,它的原理其实很简略。

bit 即比特,而 Bitmap 则是经过 bit 位来标识某个元素对应的值(支撑 0、1 两种状况),简略而言,Bitmap 自身便是一个 bit 数组。

举个简略的比方,假定有 10 个用户(ID 分别为 1~10),某天 1、3、5、7、8、9 登录体系,怎么简略的表明用户的登录状况呢?如图 1,只需求找到用户对应的位,并置 1 即可。

图 1

更多地,假如需求检查某用户当天是否登录体系,仅需检查该用户 ID 位对应的值是否为1。而且,经过核算 Bitmap 中 1 的个数便可知道登录体系的用户总数。Bitmap 已支撑的运算操作(如 AND、OR、ANDNOT 等)可以使维度穿插等核算愈加速捷。

Bitmap两个重要的特性

高功用

Bitmap 在其主战场的核算功用适当惊人。在美图,前期的核算首要依据 Hive。以美图系某 APP 数据为基准进行了简略的留存核算(即核算新增用户在次日仍然活泼的用户数量),经过 Hive(选用 left out join)耗时 139 秒左右,而 Bitmap(交集核算)仅需 226 毫秒,Hive 的耗时是 Bitmap 的 617 倍左右。如图 2 所示,其间,Hive 依据 4 节点的 Hadoop 集群,而 Bitmap 仅运用单节点单进程。

图 2

存储空间小

由于 Bitmap 是经过 bit 位来标识状况,数据高度紧缩故占用存储空间极小。假定有 10 亿活泼设备 ID(数值类型),若运用惯例的 Int 数组存储大约需 3.72G,而 Bitmap 仅需 110M 左右。当然,若要进行去重、排序等操作,存储空间的节约带来的功用盈利(如内存耗费等)也十分可观。

美图 Bitmap 运用

美图公司具有许多 APP,如美图秀秀、美颜相机、美拍、美妆相机、潮自拍等。咱们熟知的美图秀秀和美颜相机都具有千万等级的日活,前史累积的用户量更达几十亿。

大部分首要日常核算功用均依据 Bitmap,如新增、活泼、留存、晋级、回访等。 一起,咱们还支撑时刻粒度(比方天、周、月乃至年)及 APP、途径、版别、区域等多种维度,以及各维度的穿插核算等。

图 3

Bitmap 原理简略,可是仅经过 Bitmap 服务来支撑海量数据和需求比幻想中更杂乱。从 2015 年至今,从单机版到分布式,从单 APP 到各式各样 APP 的接入,从少数目标的「少数」数据到现在的海量数据和需求,咱们在 Bitmap 的实践进程中也遇到了不少的应战,其间较典型的有:

  • 百 T 级 Bitmap 索引。这是单个节点难以保护的量级,一般状况下需求凭借外部存储或自研一套分布式数据存储来处理;
  • 序列化和反序列化问题。尽管 Bitmap 存储空间占用小、核算快,但运用外部存储时,关于大型 Bitmap 单个文件经紧缩后仍可达几百兆乃至更多,存在十分大的优化空间。别的,存储及查询反序列化数据也是十分耗时的;
  • 怎么在分布式 Bitmap 存储上比较好的去做多维度的穿插核算,以及怎么在高并发的查询场景做到快速的呼应

/ 美图分布式 Bitmap—Naix /

Naix,即美图 Bitmap 服务的终究形状,是美图自主研制的通用分布式 Bitmap 服务。为了使 Naix 适用于各种场景,咱们在规划时都尽或许让相关组件和结构通用化。

Naix 的姓名来源于 Dota,在美图数据技能团队有各种「Dota 系列」的项目,如 Kunkka、Puck、Arachnia 等。将分布式 Bitmap 称作 Naix 的原因十分简略,其谐音 Next 涵义着下一代 Bitmap。

Naix体系规划

整个 Naix 体系如图 4 所示首要分为三层:外部调用层、体系中心节点层、依靠的外部存储层。

图 4

外部调用层

外部调用层分为 generator 和 tcp client。generator 是担任生成 Bitmap 的东西,原始数据、惯例数据一般存储在 HDFS 或许其他存储介质中,需求经过 generator 节点将对应的文本数据或其他数据转化成 Bitmap 相关的数据,然后再同步到体系中。tcp client 首要担任客户端运用与分布式体系的交互。

中心节点层

中心节点层首要包含三种:

  • Master 节点,即 Naix 的中心,首要是对集群进行相关的办理和保护,如添加 Bitmap、节点办理等操作;
  • Transport 节点是查询操作的中心节点,在接收到查询相关的恳求后,由 Transport 对其进行分发;
  • Data Nodes(Naix中最中心的数据存储节点),咱们选用 Paldb 作为 Bitmap 的根底数据存储。

依靠的外部存储层

Naix 关于外部存储有轻量级的、依靠,其间 mysql 首要用于对元数据进行办理,并保护调度中心状况、数据存储等,而 redis 更多的是作为核算进程中的缓存。

Naix 数据结构

index group

图 5

如图 5 所示 index group 是 Naix 最根本的数据结构,相似于惯例数据库中的 DataBase,首要用于阻隔各种不同的事务。比方在美图的事务中,美图秀秀和美拍便是两个不同的 index group。每个 index group 中可以有多个i ndex,index 相似于惯例数据库中的 table,如新增和活泼的 Bitmap 就归于两个不同的 index。

index

图 6

在每个 index 中,都有一个固化的时刻特色。由于 Bitmap 数据或许触及不同的时刻周期,经过格式化的时刻方法将不一起间周期的数据放入同一个 index。对应时刻段内的 index 触及多个维度,如版别、途径、区域等,每个维度触及不同的维度值(如 v1.0.0、v1.2.0 等),而咱们所指的 Bitmap 文件则是针对详细的维度值而言的。

数据信息字典办理

Bitmap 用于标识某个用户或元素的状况一般是指 ID,但在实践事务运用中往往并非如此。假如需求对 imei、idfa 进行核算,则需求将设备标识经过数据字典的映射转化为 ID 后再生成 Bitmap 并完结相关核算。一起,为了便利数据的保护和运用,咱们对维度、维度值也做了字典映射办理。

Naix genertor

关于 Bitmap 原始数据一般指是相似于 Mysql 记载数据、HDFS 文本文件等,而 Naix generator 的作用是将原始数据转化成 Bitmap 相关数据并同步到 Naix 体系,generator 以插件的方法支撑各种不同场景的 Bitmap 生成,再由事务方依据插件开发各自的事务逻辑。

simple plugin 是最简略的方法,也是咱们最早运用的插件。在美图,大部分的数据都是 HDFS 的原始数据,经过 Hive Client 过滤相关数据到处理服务器,再经过插件转化成 Bitmap 数据。

由于美图数据量大、事务杂乱,在之前的某个阶段,每天的数据生成需求耗费近 3 小时。假如中心出现问题再重跑,势必会影响其他的核算事务而形成严峻后果。因而咱们研制了 mapreduce plugin,希望经过分发自身的优势,加速数据生成的速度。

实践证明,运用 mapreduce plugin 终究可将挨近 3 小时的 generate 进程紧缩至 8 分钟左右(依据 4 节点的测验集群)。依据 mapreduce 的特色,在事务和数据量继续添加的状况下咱们也可以经过节点扩容或许 map、reduce 数量调整很简略的坚持继续快的 generate 速度。

第三个插件是 bitmap to bitmap plugin,针对各种时刻周期的 Bitmap 数据,用户可以经过咱们供给的 plugin 进行装备,在体系中定时地依据 bitmap 生成 bitmap。相似周、月、年这样的 Bitmap,该插件可以经过原生的 Bitmap 生成周期性的 Bitmap(例如经过天生成周、经过周生成月等),用户仅需提交生成计划,终究在体系中便会定时主动生成 Bitmap 数据成果。

Naix 存储

分片

怎么将海量数据存储到分布式体系中?一般状况下,惯例的分布式 Bitmap 都是依靠于一些相似 hbase 之类的外度存储或许依照事务切开去做分布式的存储,在核算进程中数据的查找以及数据的复制都是极大的瓶颈。经过各种测验,终究咱们采纳分片的方法,即经过固定的宽度对一切的 Bitmap 做分片;同一分片、相同副本序号的数据存储至相同节点,不同分片的数据或许会被存放在相同或许不同的节点。

图 7

分片的规划带来了不少的优点:

  • 百 T 等级的数据分布式存储问题便利的处理;
  • 并行核算:Bitmap 结构十分特别,根本上的 Bitmap 操作都可以按分片并行核算,再汇总整合。关于巨大的 bitmap 数据,也可按此方法提高速度;
  • 数据 copy 问题:一般状况下,在未分片前大部分 Bitmap 实践会依照事务将数据分隔,但当数据量大时,单个事务的数据在单节点也无法存储。当触及到跨事务的核算时,必定需求进行数据 copy。但进行分片后,天然就将这些核算依照分片分发到不同节点单独进行核算,避免了数据 copy;
  • 序列化和反序列化的问题:一般会出现在大型 Bitmap 中,但分片后一切 Bitmap 巨细根本可控,便不再有序列化和发序列化的问题;
  • 跨过 int 屏障:一般 Bitmap 完结仅支撑 int 规模,而跟着美图事务的开展,其用户增加很快便会超越 int 规模。采纳数据分片的方法,经过分片内的 id 位移,可以轻易地将分片进行横向叠加然后支撑到 long 的长度。

replication

replication 是惯例的分布式体系极其重要的特性,避免由于机器宕机、磁盘损坏等原因导致的数据丢掉。在 Naix 中,replication 支撑 index group level。

图 8

如图 8 所示,用深蓝色标识主分片,浅蓝色和蓝绿色标识剩余的副本分片。经过两个不同 replication 数量设置的 index group,以及两个 index 内部对应的两个 index,在图中咱们可以看到对应同一个 replication 下标的同一个分片,都会被存储在相同数据节点。而关于同一个分片的不同副本则必定是存储在不同节点中。

空间和文件碎片相关的优化

空间和文件碎片的优化是 Bitmap 实践中测验最多的一部分。Bitmap 依据 Long 数组或其他数字型数组完结,其数据往往过于密布或稀少,有很大的优化空间。大部分Bitmap的紧缩算法相似对齐紧缩,经过紧缩节约空间并削减核算量,在美图 Bitmap 中,前期运用 ewah(选用相似 RLE 的方法),后续切换为 RoaringBitmap,这也是现在 Spark、Hive、Kylin、Druid 等结构常用的 Bitmap 紧缩方法中。对 ewah 和 RoaringBitmap 进行功用比照,在咱们实在事务场景中测验,空间节约了 67.3%,数据耗时节约了 58%。在 query 方面,实践场景测验略有提高,但不及空间和 generate 耗时功用提高显着。

图 9

前期 Bitmap 选用文件存储,在读取时咱们进行了相似 mmap 的优化。但日常事务中存在许多细粒度维度拆分的Bitmap(比方某个途径的新增用户较少),而处理分片操作会将这些小型 Bitmap 拆分得更小。小文件关于操作体系自身的 block 和 inode 利用率极低,测验经过优化存储计划来处理小文件碎片的问题。首要调研了以下几个计划:

Redis

Redis 自身支撑 bitset 操作,但其完结作用达不到希望。假定进行简略的 Bitmap 数据 kv 存储,以 200T 的数据容量为例,每台机器为 256G,保存一个副本备份,大约需求 160 台服务器,跟着事务量的增加,本钱也会逐渐递加;

HBase

在美图大数据,HBase 的运用场景十分多。若选用 HBase 存储 Bitmap 数据,在读写功用上优化空间不大,且对 HBase 的依靠过重,很难到达预期的作用;

RocksDB

RocksDB 现在在业界的运用较为遍及。经测验,RocksDB 在敞开紧缩的场景下,CPU 和磁盘占用会由于紧缩导致不稳定;而在不敞开紧缩的场景下,RocksDB 在数据量上涨时功用衰减严峻,一起多DB的运用上功用并没有提高;

PalDB

PalDB 是 linkedin 开发的只读 kv 存储,在官方测验功用是 RocksDB 和 LevelDB 的 8 倍左右,当数据量达某个量级。PalDB 的功用乃至比 java 内置的 HashSet、HashMap 功用更优。PalDB 自身的规划有利有弊,其规划导致运用场景受限,但已根本满意 Naix 的运用场景。PalDB 源码量少,咱们也依据详细运用场景进行了简略调整。经测验,终究存储空间节约 13%,query 耗时在实践并发场景中,运用 PalDB 会有 60%以上的提高。generator 耗时略长,但由于添加了 mr 的 generator 方法故此影响可疏忽;

Naix query

在 Naix 体系中,全体的交互是在咱们自研的 rpc 服务根底上完结的(rpc 服务依据 Netty,选用 TCP 协议)。在 rpc 底层和 Naix 事务端协议都选用了 ProtoBuf。

图 10

分布式核算的进程包含节点、分片、数据存储等,而针对查询场景,咱们该怎么找到相关数据?怎么进行核算呢?

图 11

在 Naix 中,当 client 建议查询恳求到 transport 节点,transport 节点经过查询条件挑选最优的节点分发恳求。在对应的节点中依据恳求条件确认分片的挑选,每个节点找到对应分片后进行核算,将核算完结的成果结点进行聚兼并回来 client,相似于 fork-join 叠加 fork-join 的核算进程。

Naix 体系以通用的方法支撑查询:支撑操作符 ∩ ∪ - ( ) 组合表达式;用户依据运用场景挑选所需的查询 Tuple 和操作符拼装查询表达式即可,当然,咱们也封装了查询表达式的拼装转化东西由于 Naix 支撑的查询自身与事务无关,用户可以经过拼装表达式做各种查询操作。

图 12

举几个简略的比方:

  • 最简略的设备或用户定位,比方查询某个是否是某天的新增用户或许活泼用户;
  • 多维度的组合剖析,比方检查某天美拍 vivo 这个途径新增用户在第二天的留存状况;
  • 多维度的部分组合穿插剖析(数据剖析常见场景),比方核算某天美拍在百度、vivo 途径对应的 v6.0 和 v8.0 版别的活泼用户数,这就触及两个途径和两个版别穿插共 4 个组合的查询。这种操作一般用于数据剖析。包含前面两种,这些简略的查询操作均匀呼应仅需几毫秒;
  • 多维度的全穿插核算,相似于需求知道某天美拍中的途径和版别一切信息做穿插,产出这么许多级的数据成果。相似操作的功用首要看查询核算的维度数量以及触及的数据量,一般是在秒到分钟级的呼应。

/ 未来展望 /

为了将 Naix 体系推行到更多的公司事务乃至是外部场景,咱们也还在不断的完善和优化,现在正在做以下几个测验:

  • 前期咱们更多的是集中精力进行体系研制,确保可以满意需求。现在也在不断的丰厚运维东西,希望可以更便利运维来保护和办理 Naix;
  • 测验各式各样的核算优化,力求将 query 功用再提高一个台阶;
  • sql query 也在咱们的规划内,由于 sql 是被咱们更广泛承受的方法,希望能运用相似这种通用的 query 表达方法下降各种不同运用方的学习本钱。

原文发布于微信大众号 - 美图数据技能团队(gh_feb1d206d92b)