前言
zram是基于内存压缩的块设备,怎么理解,假设我们申请一个1G的zram块设备,这个块设备并没有实际的物理存储区域,是用内存模拟的,当一个128MB的文件被写入到zram的块设备,这个文件会被经过"牛逼"的压缩算法,然后保存在zram临时申请的物理内存中。
目前手机中的swap机制就是基于zram实现的,swap机制就是将不常用的内存页保存到zram块设备上,然后释放不常用的页,增加可用内存,当需要用到这块内存页的时候,再去从zram块设备上读取数据到内存上。
聪明小伙伴会问:swap机制好像很鸡肋,把一个内存页放到另一个zram块设备申请的内存页?
首先zram会有压缩算法,这样子就可以压缩内存,说白了就是拿cpu换内存,也就是时间换空间。
第二zram支持writeback功能,可以将zram中申请的物理页回写到真实的磁盘中,进一步释放内存。但是目前手机中没有开启writeback功能
目前的手机上的swap机制也就是起到了压缩内存的作用
用下图来表示
1.你可以看到1,2,3在内存中块变小了
2.除了1,2变小后还在内存里,3变小后存到了磁盘中
翻译
zram: 基于内存压缩的块设备
----------------------------------------
* 介绍
zram模块创建基于RAM的块设备,名为/dev/zram<id>(<id>=0,1,…)。
写入这些磁盘的页被压缩并存储在内存里。这些磁盘允许非常快速的I/O和压缩
提供大量的内存节省。一些用例包括/tmp存储,用作swap磁盘,/var下的各种缓存,甚至更多 :)
通过位于sysfs节点导出单个zram设备的统计信息/sys/block/zram<id>/
* 用法
这里有几种方法可以配置和管理zram设备
a)使用zram和zram_control的sysfs属性
b)使用zramctl工具,由util-linux (util-linux@vger.kernel.org)提供
这个文档中,我们将会只描述手动zram的配置的步骤,IOW,zram和zram_control sysfs的属性
为了获得更好关于zramctl的建议,请咨询util-linux文档,zramctl的man-page
或者`zramctl --help'。请注意,zram维护人员不开发/维护util-linux或zramctl,如果你
有任何疑问,请联系util-linux@vger.kernel.org
以下展示了使用zram的典型使用步骤
温馨提示
=======
为了简单起见,我们在绝大多数例子中跳过错误检查。然而,处理这些错误是你的专属责任
zram sysfs属性总是会返回错误值在出现问题的情况下
返回值的列表
-EBUSY -- 尝试修改一个不能修改的属性, 因为设备已经被初始化,请重置设备
-ENOMEM -- zram无法申请足够的内存满足你的需要
-EINVAL -- 提供的无效输入
如果你使用'echo',返回值将会被'echo'工具修改,一般来说:
echo 3 > /sys/block/zram0/max_comp_streams
if [ $? -ne 0 ];
handle_error
fi
应该足够了
1) 加载模块:
modprobe zram num_devices=4
创造4个设备: /dev/zram{0,1,2,3}
num_devices参数是可选的,告诉zram多少个设备将会被预创建. 默认值: 1.
2) 设置最大的压缩流数量
不管传递给这个属性的值是什么,ZRAM将始终分配多个压缩流 - 每个在线CPU一个 -
从而允许多个并发压缩操作. 当一些CPU离线时,分配的压缩流的数量会下降.不再有单一压缩流模式,
除非您正在运行一个UP系统或只有一个CPU在线。
了解当前有多少流可用
cat /sys/block/zram0/max_comp_streams
3) 选择压缩算法
使用comp_algorithm设备属性,可以看到可用的和当前使用的压缩算法,改变已经选择的压缩算法
(一旦设备已经初始化,将没有机会改变压缩算法)
举例:
#展示支持的压缩算法
cat /sys/block/zram0/comp_algorithm
lzo [lz4]
#选择压缩算法
echo lzo > /sys/block/zram0/comp_algorithm
暂时,'comp_algorithm'不一定显示内核支持的所有压缩算法。我们保留此列表主要是为了简化设备配置,
您可以使用'comp_algorithm'中未列出的压缩算法配置新设备。问题是,在内部,ZRAM使用CryptoAPI,
如果某些算法是作为模块构建的,则不可能列出所有他们正在使用的 例如/proc/Crypto或任何其他方法。
然而,这样做的好处是允许使用自定义加密压缩模块(实现S/W或H/W压缩).
4) 设置磁盘大小
设置磁盘大小,通过将值写到sysfs的'disksize'节点.
该值可以是字节,也可以使用mem后缀。
举例:
# 初始化/dev/zram0为50MB的磁盘空间
echo $((50*1024*1024)) > /sys/block/zram0/disksize
# 使用mem后缀
echo 256K > /sys/block/zram0/disksize
echo 512M > /sys/block/zram0/disksize
echo 1G > /sys/block/zram0/disksize
提示:
创建一个大于两倍内存大小的zram是没有意义的,因为我们期望2:1的压缩比。
请注意,zram使用大约0.1%的不使用时磁盘的大小,如此巨大的zram是浪费。
5) 设置内存限制: 可选
设置内存的限制通过写入sysfs的'mem_limit'节点.
该值可以是字节,也可以使用mem后缀,另外你可以在运行时改变这个值。
举例
# 限制/dev/zram0为50MB内存
echo $((50*1024*1024)) > /sys/block/zram0/mem_limit
# 使用mem后缀
echo 256K > /sys/block/zram0/mem_limit
echo 512M > /sys/block/zram0/mem_limit
echo 1G > /sys/block/zram0/mem_limit
# 取消内存限制
echo 0 > /sys/block/zram0/mem_limit
6) 激活:
//作为swap分区
mkswap /dev/zram0
swapon /dev/zram0
//格式化成ext4,挂载到/tmp
mkfs.ext4 /dev/zram1
mount /dev/zram1 /tmp
7)添加或删除zram设备
zram提供一个控制接口,可以动态(按需)添加和删除设备。
要添加新的/dev/zramX设备,请对'hot_add'属性执行读取操作。
这将返回新设备的设备id(意味着您可以使用/dev/zram<id>)或错误代码。
举例:
cat /sys/class/zram-control/hot_add
1
移除存在的/dev/zramX设备(X是设备号)
执行
echo X > /sys/class/zram-control/hot_remove
8) 统计:
每一个设备的统计数据在/sys/block/zram<id>/作为节点输出
导出设备属性的简要说明。更多详情请阅读文档/ABI/testing/sysfs-block-zram
Name 权限 描述
---- ------ -----------
disksize 可读可写 设置磁盘的大小
initstate 只读 展示设备的初始化状态
reset 只写 触发设备初始化
mem_used_max 只写 重置`mem_used_max'技术 (看后面)
mem_limit 只写 指出最大的内存使用用于存储压缩数据
writeback_limit 只写 指定IO zram可以以4KB为单位写入备份设备的最大写入量
writeback_limit_enable 可读可写 显示并设置写回限制功能
max_comp_streams 可读可写 可能的并发压缩操作数
comp_algorithm 可读可写 显示并更改压缩算法
compact 只写 触发器内存压缩
debug_stat 只读 此文件用于zram调试目的
backing_dev 可读可写 设置后端存储以便zram写入
idle 只写 将分配的插槽标记为空闲
use_dedup 可读可写 显示和设置重复数据消除功能
用户空间建议用以下文件读取设备状态
File /sys/block/zram<id>/stat
展示block layer的统计. 读取Documentation/block/stat.txt获得更多的信息
File /sys/block/zram<id>/io_stat
这个文件表示未被block layer统计的设备I/O的统计信息,因此在zram<id>/stat文件中不可用。
它由一行文本组成,包含以下用空格分隔的统计信息:
failed_reads 失败的读的写数
failed_writes 失败的写的次数
invalid_io 非页大小对齐的I/O请求数
notify_free 根据设备使用情况,它可能会考虑
a) 由于swap槽空闲通知而释放的页数
b) 由于bio发送的REQ_DISCARD请求而释放的页数.
前者是意味着该磁盘被用作swap磁盘,当swap槽被释放时计数;
后者是意味着该磁盘被作为有丢弃选项的文件系统,当某个块被丢弃的计数。
File /sys/block/zram<id>/mm_stat
这个文件表示设备的mm统计信息。它由一行文本组成,含以下用空白分隔的统计信息:
orig_data_size 存储在此磁盘中的未压缩数据大小。这不包括相同的元素填充页面(相同的页面),
因为没有为它们分配内存。
单位: bytes
compr_data_size 存储在此磁盘中的压缩数据大小
mem_used_total 为此磁盘分配的内存量。这包括为此磁盘分配的分配器碎片和元数据开销。
因此,可以使用compr_data_size和此统计信息计算空间分配效率。
单位: bytes
mem_limit zram用于存储压缩数据的最大内存量
mem_used_max zram用于存储数据的最大内存量
same_pages 写入此磁盘的相同元素填充页的数目。没有为此类页分配内存
pages_compacted 压缩期间释放的页数
huge_pages 不可压缩的页数
dup_data_size 重复数据消除后的数据大小
meta_data_size 为重复数据消除功能分配的元数据量
File /sys/block/zram<id>/bd_stat
这个文件表示设备的备份设备统计信息。它由一行文本组成,含以下用空白分隔的统计信息:
bd_count 写入备份设备的数据大小。
单位: 4K bytes
bd_reads 从备份设备读取的次数
单位: 4K bytes
bd_writes 写入备份设备的次数
单位: 4K bytes
9) 注销:
swapoff /dev/zram0
umount /dev/zram1
10) 重置:
写任意值到'reset'节点
echo 1 > /sys/block/zram0/reset
echo 1 > /sys/block/zram1/reset
这个将会释放这个设备申请的内存重置disksize为0.
你必须重新设置disksize在使用这个设备之前。
* 可选功能
= writeback(写回)
用CONFIG_ZRAM_WRITEBACK, zram可以将空闲/不可压缩的页写入备份存储,而不是将其保存在内存中。
要使用此功能,管理员应设置备份存储
"echo /dev/sda5 > /sys/block/zramX/backing_dev"
在设置磁盘大小之前。目前它只支持这个分区。如果管理员想使用不可压缩的页面写回,他们可以通过以下指令
"echo huge > /sys/block/zramX/write"
要使用空闲页写回,首先,用户需要声明zram页空闲。
"echo all > /sys/block/zramX/idle"
从现在起,zram上的任何页面都是空闲页面。空闲标记将被删除,直到有人请求访问block.IOW。
除非有访问请求,否则这些页仍然是空闲页。
管理员可以通过请求空闲页写回在合适的时间通过以下指令
"echo idle > /sys/block/zramX/writeback"
用这个指令zram的写回空闲页从内存到存储
如果使用flash设备时有大量的写IO,则可能会出现flash耗尽问题,
因此管理员需要设计写限制以确保整个产品生命周期的存储健康。
为了克服这个问题,zram支持"writeback_limit"功能。"writeback_limit_enable"的默认值为0,
因此它不限制任何写回。如果管理员想申请写回成本,他应该启用写回限制
$ echo 1 > /sys/block/zramX/writeback_limit_enable
一旦设置了writeback_limit_enable,zram就不允许任何写回
直到管理员通过/sys/block/zramX/writeback_limit设置预算。
(假如管理员没有开启writeback_limit_enable,
设置writeback_limit通过/sys/block/zramX/writeback_limit是无意义的)
如果管理员希望限制每天写回400M,他可以这样子做
$ MB_SHIFT=20
$ 4K_SHIFT=12
$ echo $((400<<MB_SHIFT>>4K_SHIFT)) > \
/sys/block/zram0/writeback_limit.
$ echo 1 > /sys/block/zram0/writeback_limit_enable
如果管理员希望未来重写因为预算超了,他可以通过以下做法
$ echo $((400<<MB_SHIFT>>4K_SHIFT)) > \
/sys/block/zram0/writeback_limit
如果管理员想要查看保存的写回的预算
$ cat /sys/block/zramX/writeback_limit
如果管理员想要关闭写回限制,他可以这样子做
$ echo 0 > /sys/block/zramX/writeback_limit_enable
每当重置zram时,写回限制计数将重置(例如,系统重新启动,echo 1>/sys/block/zramX/reset),
保证写回次数直到重新设置zram分配的写回预算,是用户的工作。
如果管理员想在某个时间段内测量写回计数,他可以通过/sys/block/zram0/bd_stat的第3列了解它。
= memory tracking(内存跟踪)
通过CONFIG_ZRAM_MEMORY_TRACKING,用户可以知道ZRAM块的信息。
使用*pagemap捕捉进程中的冷页或不可压缩页可能很有用。
如果你开启这个功能, 你可以看块的状态通过
/sys/kernel/debug/zram/zram0/block_state 输入如下,
300 75.033841 .wh.
301 63.806904 s...
302 63.806919 ..hi
第一列是zram的块索引。
第二列是系统启动后的访问时间
第三列是块的状态。
(s: same page
w: written page to backing store
h: huge page
i: idle page)
上面例子的第一行说第300个块在75.033841秒被访问块的状态是大页,所以它被写回后台
存储。这是一个调试功能,所以任何人都不应该依赖它来工作。
网友评论