kernel zram feature

what is zram?

Zram

wiki zram

zram(也称为 zRAM,先前称为 compcache)是 Linux 内核的一项功能,可提供虚拟内存压缩。zram 通过在 RAM 内的压缩块设备上分页,直到必须使用硬盘上的交换空间,以避免在磁盘上进行分页,从而提高性能。由于 zram 可以用内存替代硬盘为系统提供交换空间的功能,zram 可以在需要交换 / 分页时让 linux 更好利用 RAM ,在物理内存较少的旧电脑上尤其如此。

即使 RAM 的价格相对较低,zram 仍有利于嵌入式设备、上网本和其它相似的低端硬件设备。这些设备通常使用固态存储,它们由于其固有性质而寿命有限,因而避免以其提供交换空间可防止其迅速磨损。此外,使用 zRAM 还可显著降低 Linux 系统用于交换的 I/O 。

zram swap 主要原理就是从内存分配一块区域出来用作 swap 分区,每次如果内存空间不够了,不是把应用程序杀掉,而是把应用程序所占用的内存数据复制到 swap 分区,等切换回来的时候就可以直接把这部分数据恢复到内存当中,节省重新开启所需的时间。而被放到 swap 分区的应用程序,所占用的内存都是被压缩过的,比如,微信在普通内存中占用 50 MB 的空间,如果压缩率为 0.4,则放到 swap 分区里面的数据只需要 20 MB 的空间,这样 swap 分区里面就可以存放更多后台临时不用的应用程序,变相扩展了内存的大小。

内存压缩

Active memory:活跃的内存,比方可以说是开个5个App,每个占用了100M,那么就有500M活跃内存;

Inactive memory:非活跃的内存,比如关掉了三个App,那么这三个App占用的共300M内存就不再是活跃了,但是内核还会保留它。如果这时立马再启动这三个App,就会以非常快的速度打开了,因为还没有被其他App占用的Inactive memory这时又被激活了。如果很长一段时间内这些非活跃内存都没有再用的话,随着系统内存占用增加,这些非活跃内存也会被清空而用做新的用途。

那么Compressed Memory在其中扮演什么角色呢?很简单,它尽可能久的保留那些会用到的非活跃内存,以使系统更快的响应潜在的第二次响应。但是为了照顾新的内存需求,内核会压缩这些非活跃内存以腾出空间,以供新的App使用。

大概就是这么个过程,一般我们会觉得「压缩」而联想到这项技术省了内存,实际上Compressed Memory的核心价值在于是它加快了整个系统的响应速度。

当然,压缩和解压缩需要消耗一点CPU,但是现在的电脑,大多数情况下,瓶颈在内存而不是CPU

Mac OS X Mavericks增加了一个新特性——压缩内存。WWDC 2013上特别介绍了这个特性。

Fast use

在/etc/rc.local里加入:

sh# 加载zram模块
modprobe zram &&
# 分配部分内存作zram,大小建议为总内存的10%-25%,这里分配了512M.
echo $((512*1024*1024)) > /sys/block/zram0/disksize &&
# 启用zram设备为swap。zram的原理就是分出一块内存当swap分区用,其中的数据是压缩的,这样速度快,而且占用空间小。
mkswap /dev/zram0 &&
# 给zram设备分配一个高优先级,否则要是放着zram不用,去用硬盘上的swap分区就欲哭无泪了
swapon -p 10 /dev/zram0 &&
# rc.local要求最后返回0
exit 0

小疑问: zram分配的内存是动态分配吗??

动态

kernel support

kernel doc: zram: Compressed RAM based block devices

lwn: In-kernel memory compression

zram 在 2009 年的时候就进了 kernel 的 staging 目录,并于 2014 年 3 月 30 日发布的 3.14 版本正式合并入 Linux 内核主线。在 2014 年 6 月 8 日发布的 3.15 版本的 Linux 内核中,zram 已可支持 LZ4 压缩算法,而 LZO 仍然作为默认的压缩后端。内核 3.15 中的修改还改进了性能,以及经由 sysfs 切换压缩算法的能力。

如果是直接将 zram 编译到内核,那只能在代码里面直接修改 num_devices,

3.15 之前的版本代码路径是 drivers/staging/zram/zram_drv.c

3.15 及之后的版本代码路径是 ./drivers/block/zram/zram_drv.c ,默认 zram 设备个数是一个。

redhat support

The zram driver: Supportability in Red Hat Enterprise Linux

  1. Red Hat Enterprise Linux 7
  2. Red Hat Enterprise Linux 6.2
  • Q1: rhel6 是否支持 zram driver?

    • A1: Yes,红帽工程师backport过来的
  • Q2: zram dirvier是否被建议在生产上使用?

    • A2: 虽然zram driver是在driviers/staging目录,但是已经被rhel6 rhel7采纳,be used in the production environment.
  • Q3: 为何zram dirvier 现在在"staging" directory?

    • kerne2.6 开始新增了一个staging目录,这个目录下的代码含义是不稳定,需要测试等. The Linux Staging tree, what it is and is not.

    • 3.15 之前的版本代码路径是 drivers/staging/zram/zram_drv.c, 3.15 及之后的版本代码路径是 ./drivers/block/zram/zram_drv.c,

Use zram

使用方式:

方式1: 手动管理,通过echo sysfs接口zram内核参数

方式2: zramctl工具,util-linux

注意:

通过sysfs修改zram常有一些异常:
zram sysfs attributes always return negative values in case of errors.

  • -EBUSY -- an attempt to modify an attribute that cannot be changed once
    the device has been initialised. Please reset device first;
  • -ENOMEM -- zram was not able to allocate enough memory to fulfil your
    needs;
  • -EINVAL -- invalid input has been provided.

zram: Compressed RAM based block devices

step by step手动配置zram

1. Load Module

注意,通过num_devices=X参数,传递给内核模块,决定创建多少个zram块设备

modprobe zram num_devices=4
This creates 4 devices: /dev/zram{0,1,2,3}

2.压缩流的最大个数设定

Regardless the value passed to this attribute, ZRAM will always
allocate multiple compression streams

To find out how many streams are currently available:
cat /sys/block/zram0/max_comp_streams

3. 压缩算法选择

show supported compression algorithms:cat /sys/block/zram0/comp_algorithm

select lzo compression algorithm:echo lzo > /sys/block/zram0/comp_algorithm

4.Set Disksize zram 内存大小设定

Set disk size by writing the value to sysfs node 'disksize'.

默认是ram size的25%

Initialize /dev/zram0 with 50MB disksize: echo $((50*1024*1024)) > /sys/block/zram0/disksize 如果zram0 中已经包含数据,则不能通过上述命令改变disksize。需要通过reset(echo 1 > /sys/block/zram0/reset)命令后,才能改变disksize.

支持带单位: echo 512M/G/K > /sys/block/zram0/disksize

Note:
There is little point creating a zram of greater than twice the size of memory
since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the
size of the disk when not in use so a huge zram is wasteful.

5.Activate:

mkswap /dev/zram0 制作swap 
swapon /dev/zram0 使能swap

mkfs.ext4 /dev/zram1
mount /dev/zram1 /tmp

6. Deactivate

swapoff /dev/zram0
umount /dev/zram1

内存优化

zram swap块设备和普通swap块设备

linux下可以设置多次swap设备,而且可以设置swap设备的优先级。

通过下面这些,可以设置两个swap设备,并设置优先级。zram0的优先级为100,比/data/swap.img优先级高。

echo $((50*1024*1024)) > /sys/block/zram0/disksize
mkswap  /dev/block/zram0
swapon -p 100 /dev/block/zram0
mkswap  /data/swap.img
swapon -p 10 /data/swap.img

运行大应用后,可以大致看到效果

cat  /proc/swaps
Filename Type  Size Used  Priority
/dev/block/zram0                        partition  51196 42672  100
/data/swap.img                          file  204796 0  

How to use zram in el6

zram system script (fix)

create file with name zram /etc/init.d/ and paste the script like so :

# vim /etc/init.d/zram

#!/bin/bash
### BEGIN INIT INFO
# Provides: zram
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Increased Performance In Linux With zRam (Virtual Swap Compressed in RAM)
# Description: Adapted from systemd scripts at https://github.com/mystilleef/FedoraZram
### END INIT INFO
 
start() {
    # get the number of CPUs
    num_cpus=$(grep -c processor /proc/cpuinfo)
    # if something goes wrong, assume we have 1
    [ "$num_cpus" != 0 ] || num_cpus=1
 
    # set decremented number of CPUs
    decr_num_cpus=$((num_cpus - 1))
 
    # get the amount of memory in the machine
    mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
	
    #we will only assign 50% of system memory to zram
    mem_total_kb=$((mem_total_kb / 2))
 
    mem_total=$((mem_total_kb * 1024))
 
    # load dependency modules
    modprobe zram num_devices=$num_cpus
 
    # initialize the devices
    for i in $(seq 0 $decr_num_cpus); do
    echo $((mem_total / num_cpus)) > /sys/block/zram$i/disksize
    done
 
    # Creating swap filesystems
    for i in $(seq 0 $decr_num_cpus); do
    mkswap /dev/zram$i
    done
 
    # Switch the swaps on
    for i in $(seq 0 $decr_num_cpus); do
    swapon -p 100 /dev/zram$i
    done
}
 
stop() {
	for i in $(grep '^/dev/zram' /proc/swaps | awk '{ print $1 }'); do
		swapoff "$i"
	done
 
	if grep -q "^zram " /proc/modules; then
		sleep 1
		rmmod zram
	fi
}
 
status() {
        ls /sys/block/zram* > /dev/null 2>&1 || exit 0
        echo -e "-------nzram Compression Stats:n-------"
        for i in /sys/block/zram*; do
                compr=$(< $i/compr_data_size)
                orig=$( $compr)"
"
        done
        echo -e "-------nSWAP Stats:n-------"
        swapon -s | grep zram
        echo -e "-------nMemory Stats:n-------"
        free -m -l -t
}
 
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 3
        start
        ;;
	status)
		status
		;;
    *)"
	
"
      echo "Usage: $0 {start|stop|restart|status}"
        RETVAL=1

esac

save changes and give execute mode to zram

# chmod 755 /etc/init.d/zram

make zram start at boot

# chkconfig --add  zram  && chkconfig zram on

执行上面脚本,会帮你在内存中创建虚拟的block device虚拟的块设备,/dev/zramX,就像是swap空间一样


#ll /dev/zram
zram0   zram1   zram10  zram11  zram2   zram3   zram4   zram5   zram6   zram7   zram8   zram9

#ll /sys/block/zram*
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram0 -> ../devices/virtual/block/zram0
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram1 -> ../devices/virtual/block/zram1
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram10 -> ../devices/virtual/block/zram10
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram11 -> ../devices/virtual/block/zram11
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram2 -> ../devices/virtual/block/zram2
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram3 -> ../devices/virtual/block/zram3
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram4 -> ../devices/virtual/block/zram4
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram5 -> ../devices/virtual/block/zram5
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram6 -> ../devices/virtual/block/zram6
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram7 -> ../devices/virtual/block/zram7
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram8 -> ../devices/virtual/block/zram8
lrwxrwxrwx 1 root root 0 Aug 14 14:19 /sys/block/zram9 -> ../devices/virtual/block/zram9

how to use zram in rhel7

https://github.com/mystilleef/FedoraZram

Difference between zram && zswap

zram

  • Status: In staging tree (as of 3.7) and looking to move into mainline

  • Implementation: compressed block device, memory is dynamically allocated as data is stored

  • Usage: Configure zram block device as a swap device to eliminate need for physical swap defice or swap file

  • Benefits:
    Eliminates need for physical swap device. This beame popular when netbooks first showed up. Zram (then compcache) allowed users to avoid swap shortening the lifespan of SSDs in these memory constrained systems.

    A zram block device can be used for other applications other than swap, anything you might use a block device for conceivably.

  • Drawbacks(缺点):
    Once a page is stored in zram it will remain there until paged in or invalidated. The first pages to be paged out will be the oldest pages (LRU list), these are 'cold' pages that are infrequently access. As the system continues to swap it will move on to pages that are warmer (more frequently accessed), these may not be able to be stored because of the swap slots consumed by the cold pages. What zram can not do (compcache had the option to configure a block backing device) is to evict pages out to physical disk. Ideally you want to age data out of the in-kernel compressed swap space out to disk so that you can use kernel memory for caching warm swap pages or free it for more productive use.

zswap

  • Status: Posted to LKML on Dec 11th, 2012

  • Implementation: compressed in-kernel cache for swap pages. In-kernel cache is compressed, the compression algorithm is pluggable using the CryptoAPI and the storage for pages is dynamically allocated. Older pages can be evicted to disk making this a sort of write-behind cache.

  • Usage: Cache swap pages destined for regular swap devices (or swap files).

  • Benefits:

    1. Integration with swap code (using Frontswap API) allows zswap to choose to store only pages that compress well and handle memory allocation failures, in those cases pages are sent to the backing swap device.

    2. Oldest pages in the cache are pushed out to backing swap device to make room for newer pages, this solves the LRU inversion problem that a lack of page eviction would present.

  • Drawbacks(缺点):
    Needs a physical swap device (or swapfile).

REF

http://blog.csdn.net/longwang155069/article/details/51900031

posted @ 2017-08-14 16:38  苏小北1024  阅读(1953)  评论(0编辑  收藏  举报