分类目录归档:云计算

RGW NFS/ganesha 源码分析

0×1 RGW NFS Open 流程

0x 2 Ganesha 核心模块:
– MemoryManager 负责Ganesha的内存管理
– RPC SES_GSS 负责使用RPCSEC_GSS的数据传输,通常使用krb5,SPKM3或LIPKEY来管理
– NFS NFS协议,主要是消息结构模块
– Metadata(Inode) Cache: 元数据缓存
– File Content Cache: 负责数据缓存,主要是小数据。
– FSAL (File system Abstraction Layer, 抽象的访问对象)
– Hash Tables rbtree group。

内存管理:
LibC malloc / free调用,内存是采用calloc分配的。

哈希表:
redblack tree
主要守护进程
– dispatcher thread: 用于监听和分发传入的NFS、MOUNT请求。它会选择处于最空闲的worker线程然后将请求添加到这个worker线程的待处理列表中。这个线程会保留最近10分钟内的请求答复,如果在10分钟内收到相同指令(存在哈希表并用RPC Xid4值寻址),则会返回以前的请求回复。
– worker thread: Ganesha中的核心线程,也是使用最多的线程。worker线程等待dispatcher的调度,收到请求后先对其进行解码,然后通过调用inode cache API和file content API来完成请求操作。
缓存:
Cache Inode Layer将元数据与对应FSAL对象handle放入哈希表中,用来关联条目。初版的Ganesha采用’write through’缓存策略来做元数据缓存。实例的属性会在一定的时间(可定义)后过期,过期后该实例将会在内存中删除。每个线程有一个LRU(Least Recently Used) 列表,每个缓存实例只能存在于1个线程的LRU中,如果某个线程获得了某个实例,将会要求原线程在LRU列表中释放对应条目。

每个线程需要自己负责垃圾回收,当垃圾回收开始时,线程将从LRU列表上最旧的条目开始执行。 然后使用特定的垃圾策略来决定是否保存或清除条目。由于元数据缓存应该非常大(高达数百万条目),因此占满分配内存的90%(高位)之前不会发生垃圾回收。Ganesha尽可能多得将FSAL对象放入缓存的‘树型拓扑’中,其中节点代表目录,叶子可代表文件和符号链接;叶子的垃圾回收要早于节点,当节点中没有叶子时才会做垃圾回收。

File Content Cache数据缓存并不是独立于与Inode Cache,一个对象的元数据缓存和数据缓存会一一对应(数据缓存是元数据缓存的‘子缓存’),从而避免了缓存不统一的情况。文件内容会被缓存至本地文件系统的专用目录中,一个数据缓存实例会对应2个文件:索引文件和数据文件。数据文件等同于被缓存的文件。索引文件中包含了元数据信息,其中包含了对重要的FSAL handle。索引文件主要用于重建数据缓存,当服务器端崩溃后没有干净地清掉缓存时,FSAL handle会读取索引文件中的信息来重建元数据缓存,并将其指向数据文件,用以重建数据缓存实例。

当缓存不足时,worker thread会查看LRU列表中很久未被打开的实例,然后开始做元数据缓存回收。当元数据缓存回收开始时,数据缓存的垃圾回收也会同时进行:在回收文件缓存实例时,元数据缓存会问询数据缓存是否认识该文件实例,如果不认识则代表该数据缓存已经无效,则元数据回收正常进行,并完成实例缓存回收;如果认识,对应的文件缓存以及数据缓存均会被回收,随后对应的元数据缓存也会被回收。这样保证了一个数据缓存有效的实例不会被回收。

这种方式很符合Ganesha的架构设计:worker线程可以同时管理元数据缓存和数据缓存,两者一直保持一致

0×3 RGW-NFS release notes:
New NFS-Ganesha FSALexporting RGW Namespace. Runs a full
Ceph RGW under an NFS-Ganesha process. Cache coherent peer
of all gateways in the cluster.
Goals:
Add RGW/S3 as an adjunct namespace on existing POSIX
clients
Support S3 Legacy “Prefix and Delimiter” Namespace
Convention
Only supports ‘/’ delimiter currently
Build foundation for more interesting workflows, e.g.
pNFS direct placement of sharded objects (future)
consistent caching (future)
0×4 参照:

http://blog.umcloud.com/nfs-ganesha/

ceph的pool的pg修改值的计算

pg的修改
当扩大pg num的时候,有时候会遇到报错:

限制pg spliting的参数来源于mon_osd_max_split_count value。
查看配置文件

计算脚本:

结果输出

block_size的计算

If the value of the above calculation is less than the value of ( OSD# ) / ( Size ), then the value is updated to the value of ( OSD# ) / ( Size ). This is to ensure even load / data distribution by allocating at least one Primary or Secondary PG to every OSD for every Pool.
The output value is then rounded to the nearest power of 2.
Tip: The nearest power of 2 provides a marginal improvement in efficiency of the CRUSH algorithm.
If the nearest power of 2 is more than 25% below the original value, the next higher power of 2 is used.

pg与osd的对应关系查找

利用pg在pool以及osd的分布关系可以更好的分析pg的分布是否均匀

首先获取pg的query数据。利用Ansible模块获取数据。数据如下:

利用python分析该数据:

ceph rbd的新特性

ceph支持 layering,striping exclusive lock, object map,fast diff ,deep-flatten 等新的new features
layering
image的克隆操作。可以对image创建快照并保护,然后从快照克隆出新的image出来,父子image之间采用COW技术,共享对象数据。

striping v2
条带化对象数据,类似raid 0,可改善顺序读写场景较多情况下的性能。

exclusive lock
保护image数据一致性,对image做修改时,需要持有此锁。这个可以看做是一个分布式锁,在开启的时候,确保只有一个客户端在访问image,否则锁的竞争会导致io急剧下降。 主要应用场景是qemu live-migration。

object map
此特性依赖于exclusive lock。因为image的对象分配是thin-provisioning,此特性开启的时候,会记录image所有对象的一个位图,用以标记对象是否真的存在,在一些场景下可以加速io。

fast diff
此特性依赖于object map和exlcusive lock。快速比较image的snapshot之间的差异。

deep-flatten
layering特性使得克隆image的时候,父子image之间采用COW,他们之间的对象文件存在依赖关系,flatten操作的目的是解除父子image的依赖关系,但是子image的快照并没有解除依赖,deep-flatten特性使得快照的依赖也解除。

journaling
依赖于exclusive lock。将image的所有修改操作进行日志化,并且复制到另外一个集群(mirror),可以做到块存储的异地灾备。这个特性在部署的时候需要新部署一个daemon进程,目前还在试验阶段,不过这个特性很重要,可以做跨集群/机房容灾。

创建image的时候,jewel默认开启的特性包括: layering/exlcusive lock/object map/fast diff/deep flatten

Exclusive Lock
从上面可以看出,很多特性都依赖于exclusive lock,重点介绍一下。

exclusive lock 是分布式锁,实现的时候默认是客户端在第一次写的时候获取锁,并且在收到其他客户端的锁请求时自动释放锁。这个特性在jewel默认开启后,本身没什么问题, 客户端可以自动获取和释放锁,在客户端crash后也能够正确处理。

ceph性能优化的操作笔记(3)

Ceph层面的优化
参数的查询
下面的tuning参数可以通过以下命令获取

以下命令用来观察osd的性能:

1 filestore/object store 的参数
filestore queue max ops = 50000 数据盘最大接受的操作数
filestore queue max bytes = 524288000 数据盘一次操作最大的字节数(bytes)
跟踪op_queue_reserve_throttle查看是否有waiting大于max_ops或大于max_bytes. 当队列的操作数过多,或者队列中操作数据长度过大,阻塞等待。在某个操作处理结束后,_void_process_finish会唤醒

filestore queue committing max ops = 50000 #数据盘能够commit的操作数
filestore queue committing max bytes = 524288000 #数据盘能够commit的最大字节数(bytes)

filestore fd cache size: 128 #对象文件句柄缓存大小 10000 objects. (10k files x 4M/file = 40G) as cache。如果有100G内存。 100G /10 osd = 10G /4M = 2500(cache size)
filestore fd cache shards: 16 #对象文件句柄缓存分片个数
默认值128个object。如果每个object的大小为4M,每个filestore 只能cache 128*4M = 512M 。缓存文件句柄能加快文件的访问速度,建议缓存所有的文件句柄,要调高系统的句柄限制,以免句柄耗尽。建议10240

filestore_fiemap: #开启稀疏读写特性,有助于加快克隆和恢复速度

filestore_max_sync_interval: 5
filestore_min_sync_interval: 0.01

filestore_merge_threshold: 10 #pg子目录合并的最小文件数
filestore_split_multiple: 2 #pg子目录分裂乘数,默认为2
这两个值决定了一个目录下,存放object文件的个数。 默认为 10 * 2 * 16 = 320个。 如果超过这个数, 目录会自动split。 这会影响到内存中元数据的访问, 进而影响性能。filestore_merge_threshold表示, 当一个目录下的object文件数小于该值时, 目录会自动合并。两个参数控制pg目录的合并与分裂,当目录下的文件数小于filestore_merge_threshold时,该目录的对象文件会被合并到父目录;如果目录的文件数大于filestore_merge_threshold*16*filestore_split_multiple,该目录会分裂成两个子目录。设置合理的值可以加快对象文件的索引速度