1. 什么是alluxio
1.1. alluxio在学术界和工业界情况
学术界主要是南大和清华在研究。相关资料可以查看:
- 南京大学PASA大数据实验室专栏(本文的PPT均来自该参考资料,强烈推荐!)
- 高速跨平台大数据存储系统Alluxio的特性与案例介绍-pdf
国内工业界以下公司在使用:
- 百度:1000个worker的alluxio集群,总提供50TB内存存储,主要支持百度可交互式查询业务;另外个alluxio集群层次化管理2PB数据。
- 阿里:oss支持alluxio
- 去哪儿:去哪儿网:使用Alluxio(前Tachyon)实现300倍提升
更多的使用者:
1.2 为什么要使用alluxio
- 数据共享避免I/O: 这个是内存存储的优势,显而易见
- 避免数据缓存丢失:例如spark把数据放在JVM中有可能会因为JVM crash导致丢数据。alluxio通过内存数据持久化、check point和世代关系做数据恢复等手段来避免数据缓存丢失
- 不基于JVM存储数据:相比spark,alluxio不会把大量数据缓存到JVM而是存到本地内存,避免GC时候扫描大量JVM缓存数据,降低性能。alluxio采用基于内存的OffHeap的分布式存储。
2. alluxi系统框架与原理
2.1 整体架构
PS: 通信采用thrift RPC
2.2 文件组织
2.3 alluxio读写行为
2.3.1 读写类型控制数据存储层位置
2.3.2 使用定位策略控制目标worker
2.4 容错机制
- 元数据的容错: 和HDFS是很像的,通过日志实现的。Image存储了元数据,Editlog记录了最近对元数据的修改记录。
- 内存数据容错: Alluxio的特有,通过记录数据的产生过程,在发生数据丢失的时候重做
数据丢失的严重程度分为两个级别:
- 某个worker上数据丢失: 通过网络I/O从其他worker节点取数据。相比HDFS只有网络I/O,性能比较好。
- 所有worker上数据都丢失:通过Lineage根据已有的数据重做Job来恢复数据
2.4.2 通过数据冗余来保证数据容错
根据写类型来控制数据写入的模式。例如ASYNC_THROUGH模式,可以将数据同步写入其他worker,同时异步写入底层存储系统。
2.4.2 Lineage与存储层数据容错
alluxio通过在存储层保存数据的Lineage实现容错,这是在Spark中引入的思想,Lineage记录了源数据以及源数据经过什么样的计算得到的当前数据。
当数据丢失的时候,Alluxio会根据数据的Lineage进行数据的恢复,这个过程有点像Spark中的数据重算,但是它比Spark走的更远。因为Spark中的重算是在程序运行时的操作,当程序运行的时候发现某个节点挂掉了,它会重新计算来恢复数据,问题是如果整个Job已经结束之后,数据再发生丢失就没有办法了,Alluxio可以解决这个问题。因为Alluxio在存储层存储了整个数据的依赖关系,包括了这个数据是由什么样的框架,通过什么样的执行过程生成的,当数据丢失的时候Alluxio会重新启动这些应用然后生新成这些数据,实现数据恢复。
3. alluxio的重要特性与适用场景
3.1 命令行接口
完整命令行可以查看官方文档
3.2 文件系统API
关于文件系统,有以写几点需要注意:
- 一次写入语义:文件全部被写入之后就不会改变,而且文件在写操作完成之前不能进行读操作
- 本地API和兼容Hadoop的API:本地API具有更好的性能,而兼容Hadoop的API使用户可以灵活利用Alluxio,但没必要修改用Hadoop API写的代码。
3.3 alluxio-fuse
3.4 世代(Lineage)关系API
补充:
- 这里所说的Lineage信息不丢失来恢复数据应该是和数据库原理相近的。即Lineage的记录应该是有检查点的,检查点以前的数据才是可以恢复的。
- 默认情况下,世系关系是不生效的。你可以通过在配置文件中将alluxio.user.lineage.enabled属性设置为true来使其生效。
- 有JAVA API可以来访问世代关系
3.5 键值存储库API
3.6 分层存储
3.6.1 分配策略
Alluxio使用分配策略选择新数据块的写入位置。Alluxio定义了分配策略的框架,也内置了几种分配策略。以下是Alluxio已实现的分配策略:
- 贪心分配策略:分配新数据块到首个有足够空间的存储目录。
- 最大剩余空间分配策略:分配数据块到有最大剩余空间的存储目录。
- 轮询调度分配策略:分配数据块到有空间的最高存储层,存储目录通过轮询调度选出。
将来会有更多的分配策略可供选择。由于Alluxio支持自定义分配策略。你可以为自己的应用开发合适的分配策略。
3.6.2 回收策略
Alluxio使用回收策略决定当空间需要释放时,哪些数据块被移到低存储层。Alluxio支持自定义回收策略,已有的实现包括:
- 贪心回收策略:移出任意的块直到释放出所需大小的空间。
- LRU回收策略:移出最近最少使用的数据块直到释放出所需大小的空间。
- LRFU回收策略:基于权重分配的最近最少使用和最不经常使用策略移出数据块。如果权重完全偏向最近最少使用,LRFU回收策略退化为LRU回收策略。
- 部分LRU回收策略:基于最近最少使用移出,但是选择有最大剩余空间的存储目录(StorageDir),只从该目录移出数据块。
将来会有更多的回收策略可供选择。由于Alluxio支持自定义回收策略。你也可以为自己的应用开发合适的回收策略。
使用同步移出时,推荐使用较小的块大小配置(64MB左右),以降低块移出的延迟。使用空间预留器时,块大小不会影响移出延迟。
3.6.3 空间预留
空间预留器可以在存储空间被完全耗尽前试着在每一层预留一定比例的空间。用于改善突发写入的性能,也可以在回收策略连续运行时提高持续写入的边际性能增益。开启和配置空间预留器:
在Alluxio中,使用配置参数开启分层存储。默认情况下,Alluxio使用单层内存存储。使用如下配置参数可以指定Alluxio的额外存储层:
alluxio.worker.tieredstore.levels
alluxio.worker.tieredstore.level{x}.alias
alluxio.worker.tieredstore.level{x}.dirs.quota
alluxio.worker.tieredstore.level{x}.dirs.path
alluxio.worker.tieredstore.level{x}.reserved.ratio
举例而言,如果想要配置Alluxio有两级存储–内存和硬盘–,可以使用如下配置:
alluxio.worker.tieredstore.levels=2
alluxio.worker.tieredstore.level0.alias=MEM
alluxio.worker.tieredstore.level0.dirs.path=/mnt/ramdisk
alluxio.worker.tieredstore.level0.dirs.quota=100GB
alluxio.worker.tieredstore.level0.reserved.ratio=0.2
alluxio.worker.tieredstore.level1.alias=HDD
alluxio.worker.tieredstore.level1.dirs.path=/mnt/hdd1,/mnt/hdd2,/mnt/hdd3
alluxio.worker.tieredstore.level1.dirs.quota=2TB,5TB,500GB
alluxio.worker.tieredstore.level1.reserved.ratio=0.1
相关配置说明如下:
- alluxio.worker.tieredstore.levels=2 在Alluxio中配置了两级存储
- alluxio.worker.tieredstore.level0.alias=MEM配置了首层(顶层)是内存存储层
- alluxio.worker.tieredstore.level0.dirs.path=/mnt/ramdisk 定义了/mnt/ramdisk是首层的文件路径
- alluxio.worker.tieredstore.level0.dirs.quota=100GB设置了ramdisk的配额是100GB
- alluxio.worker.tieredstore.level0.reserved.ratio=0.2设置了顶层的预留空间比例是0.2
- alluxio.worker.tieredstore.level1.alias=HDD配置了第二层是硬盘驱动器层
- alluxio.worker.tieredstore.level1.dirs.path=/mnt/hdd1,/mnt/hdd2,/mnt/hdd3配置了第二层3个独立的文件路径
- alluxio.worker.tieredstore.level1.dirs.quota=2TB,5TB,500GB定义了第二层3个文件路径各自的配额
- alluxio.worker.tieredstore.level1.reserved.ratio=0.1设置了第二层的预留空间比例是0.1
定义存储层时有一些限制。首先,最多只有3个存储层。而且一层最多指定一个别名。举例而言,如果想在HDD层使用多个硬盘驱动器,可以配置alluxio.worker.tieredstore.level{x}.dirs.path为多个存储路径。
另外,可以配置特定的回收策略和分配策略。配置参数是:
alluxio.worker.allocator.class=alluxio.worker.block.allocator.MaxFreeAllocator
alluxio.worker.evictor.class=alluxio.worker.block.evictor.LRUEvictor
空间预留可以配置为开启或关闭:
alluxio.worker.tieredstore.reserver.enabled=false
3.7 支持更多底层存储系统(UFS)
3.8 统一命名空间
PS: 在UFS和alluxio文件系统创建删除文件都会一起生效。例如在UFS创建一个目录,alluxio中也会有。UFS可以自由的mount或者umount。但是必须要有一个主存储,主存储是不可以随便换的。在配置文件里面指定。其他UFS可以通过例如:mount(alluxio://host:port/Data, s3://bucket/directory)这样的命令实现。
3.9 与计算框架结合
3.10 安全性
补充知识:
alluxio提供三种认证模式:
- NOSASL: 默认的模式,不进行安全控制
- SIMPLE:启用安全认证。Alluxio文件系统能够知道访问用户的身份(采用JAAS),并简单地认为该用户的身份与他声称的一致。在用户创建目录或文件后,该用户的用户名被添加到元数据中。该用户的信息可以在CLI和UI中进行查看。
- 启用安全认证。Alluxio文件系统能够知道访问用户的身份,并且通过已定义的AuthenticationProvider对该用户身份进行确认。该模式目前在实验阶段,只在测试中使用。
3.11 Web界面
3.12 配置项设置
3.13 度量指标系统
补充信息:
关于度量指标配置:度指标量系统可以通过配置文件进行配置,Alluxio中该文件默认位于$ALLUXIO_HOME/conf/metrics.properties。自定义文件位置可以通过alluxio.metrics.conf.file配置项来指定。Alluxio在conf目录下提供了一个metrics.properties.template文件,其包括所有可配置属性。默认情况下,MetricsServlet是生效的,你可以发送HTTP请求”/metrics/json”来获取一个以JSON格式表示的所有已注册度量信息的快照。
具体度量指标的说明可以参看官方文档
4. alluxio实际应用案例介绍
这是一个真实的使用案例,英文原文:点我查看
4.1 应用需求
4.2 原先解决方案
4.3 使用alluxio的解决方案
新的处理流程:
4.4 alluxio使用示例
4.5 alluxio方案总结
参考资料:
Awesome!