开源的虚拟大数据存储系统Alluxio
(前Tachyon)的功能与使用案例介绍
顾 荣
Alluxio项目 PMC & Maintainer
南京大学 PASA大数据实验室博士研究生,
2016/05/14@DTCC 2016 (Beijing)
内容
• Alluxio简介
− Alluxio是什么
− Alluxio的发展历程
• Alluxio的系统框架与原理
• Alluxio的重要特性与适用场景
• Alluxio的实际应用案例介绍
是什么
• Alluxio是世界上第一个以内存为中心(memory-
centric)的虚拟的分布式存储系统。
• Alluxio介于计算框架和现有的存储系统之间,为
大数据软件栈带来了显著的性能提升。
Alluxio(前Tachyon)的最初诞生
• 问题
− 传统大数据分析流水线中通过磁盘文件系统(如HDFS)来共享
数据成为影响分析性能的瓶颈;
− 大数据计算引擎的处理进程(Spark的Executor,MapReduce的
Child JVM等)崩溃出错后,缓存的数据也会全部丢失;
− 基于内存的系统存储数据冗余,对象太多导致Java GC时间过长;
• 解决
− Alluxio为大数据分析流水线提供内存级数据共享服务
− 内存中的数据存放在Alluxio中,即使计算引擎处理进程崩溃,
内存中的数据仍然不会丢失
− 存放在Alluxio内存中的数据不会冗余,同时GC开销大大减小
Alluxio的发展演变
• 如今,Alluxio已发展为一个通用的分布式存储系
统,将不同的计算框架和存储系统紧密联系起来。
Alluxio的发展
• 2012年12月,Alluxio(Tachyon)发布了第一个版本
• 2016年4月,Alluxio的最新发布版本为,正在开发版本
Alluxio的发展
• 自2013年4月开源以来,已有超过50个组织机构的200多
贡献者参与到Alluxio的开发中。包括阿里巴巴,Alluxio,
百度,卡内基梅隆大学,IBM,Intel,南京大学,Red
Hat,UC Berkeley和Yahoo。
• 活跃的开源社区
内容
• Alluxio简介
• Alluxio的系统框架与原理
− 整体架构
− 文件组织
− 读写行为
− 容错机制
• Alluxio的重要特性与适用场景
• Alluxio的实际应用案例介绍
Alluxio整体架构
• Master-Worker
− Master
• 管理全部元数据
• 监控各个Worker状态
− Worker
• 管理本地MEM、SSD和HDD
• Client
− 向用户和应用提供访问接口
− 向Master和Worker发送请求
• Under File System
− 用于备份
Under File System
node 1 node 2 node 3
Master
Client
MEM
Worker1
SSD
HDD
MEM
Worker3
SSD
HDD
MEM
Worker2
SSD
HDD
Alluxio整体架构
• 基本组件
− Master-Worker
• 定时心跳通信,管理系统状态
− Worker内部
• 利用Cache机制,将热数据置于MEM
− Alluxio-UFS
• 定期备份数据
− Client-Alluxio
① Client从Master获得文件元数据信息
② 若文件数据在Alluxio中,从本地或远程Worker上读取
③ 若文件数据不在Alluxio中,从UFS上读取
Alluxio文件组织
• 元数据为Inode Tree形式
− 树状结构
− 文件和目录都为一个Inode
− 文件属性
• 构成Inode的基本信息:id、名称、长度、创建/修改时间等
• 块信息
• 备份信息
/
Dir0/ Dir1/
Dir2/ File1File0
name : File1
List<BlockInfo> : Block0, Block1, ...
checkPointPath : hdfs://xxx:yyy/zzz
...
Alluxio文件组织
• Alluxio中,文件数据按块(Block)组织
− 文件&块信息保存在Master
− 块数据保存在Worker
• Worker中以块为粒度进行存储和管理
• UFS中以文件为粒度进行存储和管理
Worker1's memory
Block0 Block1 Block2 Block3
Block4 Block5 Block9
Worker2's memory
Block4 Block5 Block7
Block8
Block6
Block9 Block1 Block2
Block4 Block5 Block7 Block8Block6 Block9File1
Block0 Block1 Block2 Block3File0
Under File System
File1
File0
Alluxio读写行为
• 使用读写类型控制数据的存储层位置
− ReadType --- 控制读数据时的行为
− WriteType --- 控制写数据时的行为
类型 取值 含义
读类型
ReadType
CACHE_PROMOTE
(默认)
如果读取的数据块在Worker上时,该数据块被移动到Worker的最高层。如果该
数据块不在本地Worker中,那么就将一个副本添加到本地Worker中。
CACHE 如果该数据块不在本地Worker中,那么就将一个副本添加到本地Worker中。
NO_CACHE 不会创建副本。
写类型
WriteType
CACHE_THROUGH 数据被同步地写入到Worker和底层存储系统。
MUST_CACHE
(默认)
数据被同步地写入到Worker,但不会写入底层存储系统。
THROUGH 数据被同步地写入到底层存储系统,但不会写入Worker。
ASYNC_THROUGH 数据被同步地写入到Worker,并异步地写入底层存储系统。
Alluxio读写行为
• 使用定位策略控制目标Worker
− 需要向Worker中写数据块时,决定使用哪个Worker
取值 含义
LocalFirstPolicy
(默认)
首先尝试使用本地Worker,如果本地Worker没有足够的容量容纳一个数
据块,那么就从有效的Worker列表中随机选择一个Worker。
MostAvailableFirstPolicy 使用拥有最多可用容量的Worker。
RoundRobinPolicy
以循环的方式选取存储下一个数据块的Worker,如果该Worker没有足够
的容量容纳一个数据块,就将其跳过。
SpecificHostPolicy 返回指定主机名的Worker。
Alluxio容错机制
• Master
− 支持使用ZooKeeper启动多个Master
− 日志 Journal : EditLog + Image
• Worker
− 由Master监控,失效时自动重启
• 备份Checkpoint & 世系关系 Lineage
内容
• Alluxio简介
• Alluxio的系统框架与原理
• Alluxio的重要特性与适用场景
− 分层存储
− 更多的底层存储系统
− 统一命名空间
− Alluxio-FUSE
− 与计算框架相结合
− 键值存储库
− Web界面
− 其他特性
• Alluxio的实际应用案例介绍
分层存储
• 为什么需要多级存储?
− 内存大小有限
• 两个概念
− StorageTier
• 存储层,对应存储介质,如内存、SSD、硬盘
− StorageDir
• 数据块存放在Alluxio Worker的本地目录,通常对应一块磁盘设备
• 一个StorageTier包含一个或多个StorageDir
• 数据块管理
− Allocator ---- 选择分配哪个StorageDir里的空间
• GreedyAllocator、MaxFreeAllocator、RoundRobinAllocator
− Evictor ---- 选择撤销哪个StorageDir里的哪些数据块
• GreedyEvictor、LRUEvictor、LRFUEvictor、PartialLRUEvictor
分层存储
• 写文件
− Client写一个数据块
• 读文件
− Client读一个数据块
• 读类型是CACHE_PROMOTE,首先将数据块从SSD或者HDD移动到MEM,然后再读取
MEM中的数据块
• 读类型不是CACHE_PROMOTE,从存放该数据块的存储层直接读取数据
• Pining files
− Pining经常访问的文件在内存,永远不会被替换
• Space reserver
− 保留部分空闲空间 ---- 提升突发性写的性能
空闲空
间小于
xMB
Evictor撤销内存
中的部分数据块
申请xMB空间
是
否 分配xMB空间
Allocator选择
一个存储目录
分层存储适用场景
• 提升大部分应用的I/O性能
− 在充分利用内存的同时保证了存储容量
− 不同的分配/替换策略适用于不同的访问模式
− …
• 充分利用多种存储设备
− 除内存外,也能利用SSD进行加速
− 使用多个存储层目录进行负载均衡
• …
更多的底层存储系统
• 支持不同的底层存储,用于备份
− GlusterFS、(secure) HDFS、NFS、Amazon S3
− Aliyun OSS、OpenStack Swift、Google Cloud Storage
• 通用的接口,能够扩展更多底层存储系统
• UnderFileSystemFactory
• UnderFileSystem
底层存储系统的适用场景
• 对Alluxio中的重要数据进行备份
− 结合ASYNC_THROUGH的写类型,异步备份数据,既
保证了性能,又提供了可靠性
• 将数据迁移至Alluxio
− 将数据从原先基于磁盘的存储迁移至Alluxio,利用内
存加速
• …
统一命名空间
• 透明命名机制
− 保证Alluxio和其底层存储系统的命名空间是一致的
− 用户使用统一路径访问
统一命名空间
• 统一命名空间
− 能够将多个数据源中的数据挂载到Alluxio中
− 多个数据源使用统一的命名空间
− 用户使用统一路径访问
统一命名空间的适用场景
• 将数据迁移至Alluxio
− 将数据从原先基于磁盘的存储迁移至Alluxio,利用内
存加速
− 在应用中使用统一路径访问Alluxio和底层存储系统
• 管理不同数据源中的数据
− 将数据从不同数据源迁移至Alluxio,利用内存加速
− 在应用中使用统一路径访问不同数据源中的数据
− 实现不同数据源之间的数据共享
• …
Alluxio-FUSE
• 能够在Linux的本地文件系统中挂载Alluxio
− 利用Linux libfuse功能包
− 挂载为Linux本地文件系统中的一个目录
• 方便快捷的使用方式
$ mount <dir>
− 像使用本地文件系统一样使用<dir>
− 支持的操作
• open
• read
• lseek
• write
Kernel
Userspace
cat /tmp/alluxio-file
glibc
VFS
FUSE
NFS
Ext4
...
glibc
libfuse
Alluxio
Alluxio-FUSE适用场景
• 将传统并行计算迁移至Alluxio,利用内存加速
− CephFS、Glusterfs、Lustre -> Alluxio
• 对单机应用使用多节点内存进行加速
• 为普通用户提供一个大容量的内存文件系统
• …
与计算框架相结合
• 使用Alluxio作为计算框架的存储系统
− Spark、Hadoop MapReduce、Flink
− H20、Impala、…
• 不需改动现有应用源码
• 存储路径 “hdfs://ip:port/xxx” -> “alluxio://ip:port/xxx”
− Zeppelin
• 默认集成Alluxio,使用Alluxio作为解释器
与计算框架结合的适用场景
• 加速大数据应用
− 充分利用本地内存加速
− 原有应用能够直接使用Alluxio作为数据源
− 原有的数据能够被自动迁移至Alluxio
• 在不同计算框架间共享数据
− 多个应用/平台使用统一的命名空间
• …
键值存储库
• Alluxio的键值(key-value)存储功能
− 创建一个键值存储库并且把键值对放入其中
− 键值对放入存储后是不可变的
− 键值存储库完整保存后,打开并使用该键值存储库
• API样例
KeyValueSystem kvs = KeyValueSystem
.Factory().create();
KeyValueStoreWriter writer = (
new AlluxioURI("alluxio://path/my-kvstore"));
("100", "foo");
("200", "bar");
();
KeyValueStoreReader reader = (
new AlluxioURI("alluxio://path/kvstore/"));
("100");
(“300”); //null
();
Alluxio
KV Store
batch put
<K1, V1>
<K2, V2>
<K3, V3>
<Ka, Va>
<Kb, Vb>
<Kc, Vc>
<Kd, Vd>
<1, foo>
<2, bar>
K1
get
2
V1 foo
键值存储库适用场景
• 提供结构化数据的存储
− 键值对结构
− 表结构
− 图数据
− …
• 优化现有应用
− 以键值对方式存储中间结果,避免复杂的文件解析过
程
− 为现有的键值应用提供更大的内存存储空间
− …
Web界面
• 以可视化方式便于用户查看和管理
− Master、Worker的基本运行状态和信息
− Alluxio系统的配置信息
− 浏览文件系统
− 文件内容和文件块信息
− …
• 使用浏览器打开
− Master WebUI [http://<MASTER IP>:19999]
− Worker WebUI [http://<WORKER IP>:30000]
Web界面
• Master WebUI例
• Worker WebUI例
Web界面的适用场景
• 方便快捷的查看整个系统状态
− 运行状态,节点个数,系统版本等基本信息
− 整体容量使用情况
− 每个Worker的状态,容量使用等
• 浏览文件系统
− 快速查看文件/目录结构
− 预览文件内容
− 下载Alluxio文件到本地
• …
其他特性—命令行接口
• 运行方式
− bin/alluxio fs [command]
• cat
• chmod
• copyFromLocal
• copyToLocal
• fileInfo
• ls
• …
• 路径表示
− alluxio://<master-address>:<master-port>/<path>
− 支持通配符 *,如:`bin/alluxio fs rm /data/2014*`
其他特性—文件系统API
• 以Java API的方式提供Alluxio的访问接口
− 创建、写文件
FileSystem fs = ();
AlluxioURI path = new AlluxioURI("/myFile");
FileOutStream out = (path);
(...);
();
− 读文件
FileSystem fs = ();
AlluxioURI path = new AlluxioURI("/myFile");
FileInStream in = (path);
(...);
();
− 最新版本Java API Doc
(
• 兼容现有的Hadoop FileSystem接口
− 在MapReduce、Spark等作业中以“alluxio://”代替“hdfs://”
其他特性—世系关系API
• 世系关系 Lineage
− 记录文件之间的世系关系,在数据丢失时通过重计算
进行恢复
− 例:构造并创建世系关系
AlluxioLineage tl = ();
List<AlluxioURI> inputFiles = (new AlluxioURI("/inputFile"));
List<AlluxioURI> outputFiles = (new AlluxioURI("/outputFile"));
JobConf conf = new JobConf("/tmp/");
CommandLineJob job = new CommandLineJob("", conf);
(inputFiles, outputFiles, job);
其他特性—安全性
• 安全认证
− Alluxio能够识别访问用户的身份,这是访问权限以及
加密等其他安全特性的基础
− 当用户(客户端)连接Alluxio(服务端)时,需要特
定的用户、密码或其他认证方式
• 访问权限控制
− 以文件为粒度进行访问权限控制
− 类似POSIX标准的访问权限模型
• 用户权限、用户组权限、其他用户权限
• 读r、写w、执行x
其他特性—配置项设置
• 配置属性
− 在文件中的””项
− 共有配置项、Master配置项、Worker配置项、用户
配置项、集群管理配置项、安全性配置项
• 系统环境属性
− 在conf/文件中定义为环境变量
• 在Web界面上查看
其他特性—度量指标系统
• 实时统计整个Alluxio系统的度量信息
− 常规信息: 集群的整体度量信息(如:CapacityTotal)
− 逻辑操作: 执行的操作数量(如:FilesCreated)
− RPC调用: 每个操作的RPC调用次数(如:
CreateFileOps)
• 支持以不同方式显示这些信息
− ConsoleSink: 输出到控制台
− CsvSink: 每隔一段时间将度量指标信息导出到CSV文
件中
− JmxSink: 查看JMX控制台中寄存器的度量信息
− GraphiteSink: 给Graphite服务器发送度量信息
− MetricsServlet: 显示到Web UI中
其他特性—度量指标系统
• WebUI中的度量信息
内容
• Alluxio简介
• Alluxio的系统框架与原理
• Alluxio的重要特性与适用场景
• Alluxio的实际应用案例介绍
− 一个图计算任务
− Barclays Personal and Corporate Bank
− 更多使用案例
一个大规模图计算任务
• 目标
− 通过邻居关系计算两者的相似度
− 迭代计算节点间的关系
• 难点
− 每次迭代会产生大量的中间结果
图计算解决方案
• Bagel on Alluxio
− Bagel – Spark中的图计算框架
− 每个作业由一系列迭代过程组成,在每轮迭代中
• 在每个点上利用邻居节点的信息进行用户定义的计算
• 更新每个点自身的状态
• 为下一轮迭代准备数据
− 每轮迭代产生的中间结果存放在Alluxio中
Compute
Vertex
Aggregate
Generate
Alluxio
图计算性能结果
• 通过结合Alluxio,在原先的
Spark上提升了20%的性能
• 在Spark + 两层Alluxio中, 2/3
的数据存储在SSD上,其余
1/3存储在HDD上
• 单层SSD和两层(SSD+HDD)
的Alluxio带来的性能提升区
别不大
Barclays的应用需求
• 数据来源
− 银行事务数据
− 存储在关系型数据库中
• 计算任务
− 批量处理某一时间段的数据
− 多个应用使用同一批数据
• 时间需求
− 日常应用,每天都要对前一天的数据进行分析
原先的解决方案
• 使用Spark进行计算
− 并行的JDBC从数据库中读取数据
− 使用DataFrame格式进行计算和分析
原先解决方案的缺陷
• 数据读取过程成为瓶颈
− 将大规模的数据表从JDBC读入,转换成DataFrame耗
时巨大
− 不同Spark任务间不能共享内存,每个应用都要从
JDBC读一遍数据
进一步解决方案
• 使用Alluxio(Tachyon)管理数据
− 输入的大规模数据表存储在Alluxio中,所有应用共享
− 计算中产生的中间结果也存储在Alluxio中,Spark任务
间共享
− 使用Alluxio对Spark任务本身进行加速
示例
• 将DataFrame存储到Alluxio
(“alluxio://master_ip:port/mydata/”)
val dataframe : DataFrame =
(“alluxio://master_ip:port/mydata/”)
• 将Spark RDD存储到Alluxio
(“alluxio://master_ip:port/mydata/”)
val rdd : RDD[MyCaseClass] = [MyCaseClass]
(“alluxio://master_ip:port/mydata/”)
完整的解决方案架构