随着云计算、移动通信、IoT的发展,传统的块设备和文件系统的方式访问面临着越来越多的局限,对象存储应运而生。对象存储使得应用或端设备直接通过web或http访问数据成为可能。其次,由于对象存储的分布式存储的特点,天然地适合于大规模非结构化数据的存储的应用场景,如备份、归档、文件共享等。
本文介绍如何基于开源的Swift对象存储技术设计并构建一套海量、安全、高可靠、低成本的云存储集群。
构建之前
在进行正式的设计和构建之前,一定要清楚存储系统的使用场景并且明晰存储的需求。
目前云存储主要适用于以下场景:
- 提供企业内部使用的云盘及文件共享等服务;
- 备份和归档
- 作为公有云厂商提供云存储服务
- 作为私有云的一部分,提供存储
针对具体的场景,我们可以从以下两个方面考虑具体的需求:
存储需求:
- 容量:存储容量、预期未来的增长速度
- 数据的可靠性要求: Replica数、Erasure Code
访问方式:
- 访问用户的数量、用户访问的频率、同时访问用户的数量
- 读、写、修改
- 访问的性能要求:延时、带宽
- 以大文件为主,还是小文件为主
- 访问的可用性要求
系统设计
设计存储系统,本质上是在性能、容量、可靠性、可用性、成本、安全等方面进行trade-off,从而设计出一套最适合组织需求的系统。不要期望one-size-fit-all。在进行正式的系统实现前,应该构建一套PoC系统,该PoC系统与实际系统的大小比例应该在1:10到1:100之间。
- 对PoC系统进行调优甚至调整,以便达到你要求的性能
- 对该系统进行扩展,并进行持续的性能调优,以保持你的PoC时达到的性能。
PoC系统达到期望目标并稳定运行以后,再对PoC系统进行扩展,变为实际的生产系统。
1)服务器选型
一个典型的Swift存储集群中,至少包含两种节点:存储节点和代理节点。选择服务器无非考虑硬盘、CPU、内存及网卡。我们在选择存储节点时往往首先考虑硬盘,然后结合CPU、内存的需求,来决定服务器的选型及服务器的数量。
硬盘
通过如下公式可以计算出所需要的磁盘空间:
所需要的磁盘空间(GB) = 用户有效的存储容量(GiB)* 副本数 * 1.087
其中,1.087是考虑文件系统(XFS)的损耗和GiB到GB的转换。
硬盘数 = 所需要的硬盘空间 / 所选择的单硬盘容量
服务器数 = 硬盘数 / 服务器盘位数
注意实际需要的服务器数量比此时计算得到的服务器还要多,主要是由于:
1)上面的计算公式中并没有考虑操作系统所占硬盘的数量。
2)上述公式中只计算了对象的使用空间。Swift中还需要考虑Account和Container。根据经验,Account和Container所使用的空间大约是对象所使用空间的1%~2%。另外,考虑到Account和Container存储元数据,需要经常访问,因此考虑性能,一般使用SSD来存储Account和Container。
3)在决定服务器数量及硬盘大小时,还需要考虑单个硬盘的成本、服务器的成本及系统的可用性。
CPU
CPU核数 = (服务器硬盘数量 * CPU核数与硬盘数之比) / CPU核的频率
CPU核数与硬盘数之比的选择取决于CPU频率和应用场景:小文件、高吞吐、高并发的场景需要更高的比例,如2/3;大文件低并发的场景下,可能只需要1/4. 根据经验,一般情况下选择1/2到2/3之间,然后根据实际情况进行优化。
内存
存储节点中内存主要用来运行Swift服务进程和缓存XFS的inode和swift的部分目录。每个inode节点大小为256字节,再加上hash_dir, suffix_dir和partition目录,因此每个对象约需要1KB的缓存。可以根据存储容量及对象大小计算出对象个数,来估计所需的内存大小。
但是,考虑到成本,一般情况下不会把所有对象的索引数据都进行缓存。根据经验,每个硬盘1GB内存应该是一个很好的起点,我们可以在此基础上进行更多的优化。
网卡
根据部署方式和规模大小,一般可以把Swift集群划分为3到5个网络:
public网络:对外提供API访问
内部网络:用于节点之间的数据通信,一般情况下,该网络上的流量不加密
管理网络:管理和监控集群的状态及服务等。
带外网络:IPMI管理网络
数据复制网络:大规模情况下,可能考虑专门的网络来负责数据的复制。
基于以上的网络,一般考虑专门的网卡或VLAN。
至于代理节点,由于代理节点处理用户的请求,并将用户数据写到存储节点或从存储节点读取数据,因此对CPU的需求非常大。同时,不对数据数据进行硬盘IO操作,因此硬盘只需要满足操作系统和日志等的使用即可。
注意服务器的选型不是一个瀑布式的过程,而需要综合考虑硬盘,CPU,内存,网卡,并结合市场情况,选择满足需求的、高性价比的服务器配置。
2)存储架构设计
一个典型的Swift集群拓扑如下图。
典型的情况下,节点可以承担下面三种服务组合中的一种:
- Proxy,Account,Container (PAC)
- Object Services(O)
- All Services(Proxy,Account,Container,Object)(PACO)
小规模的部署(有效容量<=1PB)时,一般采用PACO的方式;大规模的部署(有效容量超过10PB)时,一般考虑采用PAC和O分别处于不同节点的方式;中等规模的部署(有效容量大于1PB且小于10PB)时,可以根据具体的业务需求及以后的扩展性来决定服务的分布方式。
另外,Swift允许将一个集群根据物理位置的不同划分为不同的域(Region),可用于异地容灾(域A包含两个副本,域B包含一个副本)和跨域访问(数据副本均匀地分布在每一个域中)。由于Swift提供读亲和性和写亲和性的功能,所以对跨域的集群,读写会尽量落在本地域进行,从而减少对性能的影响。
系统调优
一个Swift读写过程关系到服务器、硬盘、内核、文件系统、缓存、网络以及Swift的相关服务等各方面,因此性能调优是一项系统工程。此处只介绍典型的配置:
- 选择合适的块大小。可以调整的块大小包括:代理服务器读写的客户端块大小,代理服务器读写时对象的块大小,对象服务器读写的磁盘块大小和对象服务器从代理服务器读写的块大小。
- 数据盘采用JBOD模式,不要使用RAID
- Object服务的workers=auto
- 其他后台进程,主要根据服务器的负载及需求情况,调整interval,每次处理的任务大小,并发数等。
- 网络设置为Jumbo Frame
设计和构建一个Swift集群是一件复杂的任务,涉及到服务器,硬盘,网络,拓扑规划,性能调优,需求分析等各个方面,需要综合考虑。另外,系统搭建以后,依然需要对系统进行持续的监控,运营和优化,并针对未来的需求作出及时的调整。
参考资料:
https://www.swiftstack.com/docs/admin/hardware.html
《OpenStack Swift: Using, Adminstering and Developing for Swift Object Storage》 Joe Arnold
https://blog.csdn.net/mirale/article/details/22049219