原文首发于博客园,作者:后青春期的Keats;地址:https://www.cnblogs.com/keatsCoder/ 转载请注明,谢谢!

Linux 配置优化

我们在使用 Redis 过程中,可能更多的关注 Redis 本身的一些配置优化,如 AOF、RDB 配置、数据结构配置优化等。但是很少关心 Redis 的载体,服务器的优化。而这往往为我们的项目运行带来灾难性的打击。因此服务器优化也是必不可少的

内存分配控制

Redis启动时,可能会出现下面的日志

# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

overcommit 是 Linux 的一种内存处理机制:Linux 对绝大多数内存申请都会回复 yes,以便运行更多的程序。因为申请内存后,并不会马上使用内存。这种机制就是 overcommit 。

而 overcommit_memory 是用来设置内存分配策略的,有三种取值

含义
0 内核检查是否有足够可用内存,有则通过。没有则申请失败,并返回错误给进程
1 表示内核允许超量使用内存直到用完为止
2 表示内核绝不过量的使用内存

日志中 Background save 指的是 bgsave 和 bgrewriteaof 。根据操作系统的配置,如果 overcommit_memory 设置为 0 则可能会造成内存申请失败而导致后台持久化失败。因此 Redis 建议将这个值设置为 1 是为了 fork 操作在低内存下也能执行成功。

设置方法

通过命令修改,立即生效。重启后会失效

sysctl vm.overcommit_memory=1

再将改动写入系统配置文件,使其永久有效

echo "vm.overcommit_memory=1" >> /etc/sysctl.conf

建议

采用 Redis 建议的配置是为了在极端情况下 Linux 可以挤出来一些内存供 Redis 备份,但是更建议优先配置好 maxmemory ,给机器留 20%~30% 的空闲内存

硬盘虚拟内存

swap 是指当物理内存不足时,拿出部分硬盘空间当 SWAP 分区(虚拟成内存)使用。我们都知道硬盘的读写速度相对于内存实在是太鸡肋,对于高并发、高吞吐的应用来说,磁盘IO通长会成为系统瓶颈。Linux 系统中 swappiness 的值控制操作系统使用 swap 的倾向程度。

查看内核版本:

uname -sr
说明
0 内核版本 3.5 及以上 宁愿使用 OOM Killer 也不使用 SWAP;内核版本 3.4 及更早则反之
1 内核版本 3.5 及以上 宁愿使用 OOM Killer 也不使用 SWAP
60 默认值
主动使用 SWAP

PS:OOM Killer 是指当 Linux 发现操作系统内存不足时,主动杀死一些非内核进程的操作

设置方法

echo {value} > /proc/sys/vm/swappiness

echo vm.swappiness={value} >> etc/sysctl.conf

监控swap

查看 Swap 的总体情况

free -m

最后一行即展示了 Swap 的使用情况,一共 2047 Mb,以使用 0 Mb,空闲 2047 Mb

实时查看 Swap 的使用

参数 si 表示 swap in ,so 表示 swap out 在我的机器上都是 0 表示没有使用交换

查看指定进程的 Swap 情况

通过 ps -ef |grep redis 查看 Redis 进程号,例如 1621

通过 cat /proc/1621/smaps | grep Swap 命令查看每个内存块 Redis Swap 的使用情况

THP 内存页大小

Redis 启动时可能会看到下面的日志

WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.

提示告诉我们建议修改 Transparent Huge Pages (THP) 的配置,Linux kernel 在 2.6.38 内核增加了 THP 特性,支持大内存页(2MB)分配,默认开启。开启后可加快 fork 子进程的速度,但是 fork 操作后,每个内存页从原来的 4KB 变为 2MB,会大幅加重重写期间父进程内存消耗。同时每次写命令引起的复制内存页单位放大了512倍。会拖慢写操作的执行时间。造成大量的写操作慢查询因此 Redis 日志中建议禁用它。方法如下:

echo never > /sys/kernel/mm/transparent_hugepage/enabled

另外在 /etc/rc.local 中追加

echo never > /sys/kernel/mm/transparent_hugepage/enabled

对于某些发行版本(例如红帽6以上)配置文件不在这个位置(在 /sys/kernel/mm/redhat_transparent_hugepage/enabled),但是 Redis 检查 THP 是写死的此位置,所以虽然这么修改后 Redis 不报警然而实际是没有作用的,需要注意。应该改动对应位置的值

使用NTP 同步时间

在集群或哨兵环境中,多台服务器使用相同的网络时间协议同步时间能更方便的阅读日志,排查问题

可以设置定时任务同步时间

crontab -u //设定某个用户的cron服务
crontab -l //列出某个用户cron服务的详细内容
crontab -r //删除某个用户的cron服务
crontab -e //编辑某个用户的cron服务
crontab -i //打印提示,输入yes等确认信息

添加每小时执行一次的任务

0 * * * * /usr/sbin/ntpdate cn.pool.ntp.org > dev/null 2>&1

最大连接数限制

通过 ulimit -a 命令查看和设置当前用户进程的资源数,其中包含 open files 参数,是单个用户同时打开的最大文件描述符个数。虽然 Redis 中可以配置最大的客户端连接数(默认 10000) 。Redis 内部最多使用 32 个文件描述符。当 open files = 4096 时,Redis 最大提供 4096-32=4064 个连接。因为它不能突破操作系统的限制。如果需要,使用如下命令修改:

ulimit -Sn {max-open-files}

TCP backlog

tcp backlog 配置的是 tcp 握手时候的队列大小。如果该值过小。会导致高并发场景下部分连接第三次握手ACK被丢弃。关于 backlog

The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

Redis 启动时,会告诉我们系统配置中该值是 128,而 Redis 511。这个 511 是没用的,因为系统比这个小。需要修改系统 backlog 的值

echo 511 > /proc/sys/net/core/somaxconn

参考文献:

《Redis开发与运维》 --- 付 磊 张益军

Redis开发运维的陷阱及避坑指南的更多相关文章

  1. 一站式学习Redis 从入门到高可用分布式实践(慕课)第六章 Redis开发运维常见问题

    fork操作 1.同步操作 2.与内存量息息相关:内存越大,耗时越长(与机器类型有关) 3.info:latest_fork_usec 进程外开销 AOF追加阻塞 不知道哪个命令??? 单机多实例部署 ...

  2. (视频)《快速创建网站》 4.1 为啥造软件不同于造汽车,为啥是软件就一定会有Bug - 构建开发运维一体化(DevOps)

    本文是<快速创建网站>系列的第9篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http://devopshub.cn/tag ...

  3. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上)

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上) Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 1) 开发 ...

  4. Devops 开发运维高级篇之容器管理

    Devops 开发运维高级篇之容器管理 安装docker Dockerfile镜像脚本入门制作 Harbor镜像仓库安装及使用 不过多解释docker直接秀基操 安装docker:(jenkins服务 ...

  5. Devops 开发运维高级篇之微服务代码上传和代码检查

    Devops 开发运维高级篇之微服务代码上传和代码检查 微服务持续集成(1)-项目代码上传到Gitlab 微服务持续集成(2)-从Gitlab拉取项目源码 微服务持续集成(3)-提交到SonarQub ...

  6. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成--部署方案优化 之前我们做的方案部署都是只能选择一个微服务部署并只有一台生产服务器,每个微服务只有一个 ...

  7. 前端避坑指南丨辛辛苦苦开发的 APP 竟然被判定为简单网页打包?

    传统混合移动App开发模式,通常会使用WebView作为桥接层,但随着iOS和Android应用商店审核政策日趋严格,有时会被错误判定为简单网页打包成App,上架容易遭到拒绝. 既然可能存在风险,那我 ...

  8. CEF避坑指南(一)——下载并编译第一个示例

    CEF即Chromium Embedded Framework,Chrome浏览器嵌入式框架.它提供了接口供程序员们把Chrome放到自己的程序中.许多大型公司,如网易.腾讯都开始使用CEF进行前端开 ...

  9. electron 编译 sqlite3避坑指南---尾部链接有已经编译成功的sqlite3

    electron 编译 sqlite3避坑指南(尾部链接有已经编译成功的sqlite3) sqlite很好用,不需要安装,使用electron开发桌面程序,sqlite自然是存储数据的不二之选,奈何编 ...

随机推荐

  1. coding++:MySQL-ERROR:Column 'complaint_settlement_id' in field list is ambiguous

    (多表查询出现的问题)列'ID'在字段列表中重复,其实就是两张表有相同的字段,但是使用时表字段的名称前没有加表名,导致指代不明. 如 前面加上表名前缀就没问题了.

  2. Crash

    一.Crash类型 crash 一般产生自 iOS 的微内核 Mach,然后在 BSD 层转换成 UNIX SIGABRT 信号,以标准 POSIX 信号的形式提供给用户.NSException 是使 ...

  3. Mac LaTex中文环境搭建

    为了在博客上写公式,折腾了一晚上Mac上的LaTex的环境搭建,本文对步骤进行记录. 系统:Mac OSX 10.10.5 软件准备 1) MacTex 2015 Distribution (Tex的 ...

  4. vue中使用阿里图标库iconfont和在旧有的iconfont中添加新的图标

    第一步 下载样式http://www.iconfont.cn/选择图表,点击加入购物车 第二步 解压下载文件 第三步 修改文件名称 与 iconfont.css 名路径 第四步 将@font-face ...

  5. Java进行二元操作类型转换

    当对两个数值进行二元操作时,先要将两个操作数转换为同一种类型,然后再进行计算. 如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型. 否则,如果其中一个操作数是float ...

  6. DOS命令集

    1.ASSOC显示或修改文件扩展名关联.ASSOC [.ext[=[fileType]]]  .ext      指定跟文件类型关联的文件扩展名  fileType  指定跟文件扩展名关联的文件类型键 ...

  7. 【前端】HTML总结

    一. HTML介绍:---------------------------------------1. 什么是HTML?   超文本标记语言,  <标签名>--标记(标签.节点)   2. ...

  8. 开启sftp服务日志并限制sftp访问目录

    目录导航 目录导航 开启sftp日志 修改sshd_config 修改syslogs 重启服务查看日志 限制sftp用户操作目录 前提说明 1. home目录做根目录 2. 单独创建目录做根目录 方法 ...

  9. 学习《深入应用c++11》2

    &&   universal references(未定的引用类型),它必须被初始化,它是左值还是右值取决于它的初始化,如果&&被一个左值初始化,它就是一个左值;如果它 ...

  10. 测量C++程序运行时间

    有个很奇怪的现象,我自认为写得好的文章阅读量只有一百多,随手写的却有一千多--要么是胡搞,要么是比较浅显.纵观博客园里众多阅读过万的文章,若非绝世之作,则必为介绍入门级知识的短文.为了让我的十八线博客 ...