美文网首页
[047][译]zram.txt

[047][译]zram.txt

作者: 王小二的技术栈 | 来源:发表于2020-03-27 21:14 被阅读0次

    前言

    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秒被访问块的状态是大页,所以它被写回后台
    存储。这是一个调试功能,所以任何人都不应该依赖它来工作。
    

    相关文章

      网友评论

          本文标题:[047][译]zram.txt

          本文链接:https://www.haomeiwen.com/subject/cztruhtx.html