How to remove Redis warning on Docker: Memory overcommit must be enabled 如何删除 Docker 上的 Redis 警告:必须启用内存过量使用
Carlos Delgado 卡洛斯·德尔加多
- October 10, 2023 2023 年 10 月 10 日
- 12.6K views 12,600 次观看
Learn how to remove the Redis warning overcommit_memory is set to 0, background save may fail under low memory conditions in your Redis Container.
了解如何删除 Redis 警告 overcommit_memory 设置为 0,在 Redis 容器内存不足的情况下后台保存可能会失败。
Redis is pretty famous nowadays, it can be used as a database, a cache system, or even a message broker. I would end up repeating myself trying to list all the possible use cases of Redis in projects out there, so let's keep it simple, Redis is used everywhere in production projects and therefore, it's pretty usual to have a local instance for development purposes.
Redis 现在非常有名,它可以用作数据库、缓存系统,甚至消息代理。我最终会重复自己尝试列出项目中 Redis 的所有可能用例,所以让我们保持简单,Redis 在生产项目中随处使用,因此,通常有一个用于开发目的的本地实例。
After trying to implement a new Redis container to help me out with a Django project, I used a pretty basic configuration to start a container with Redis 7.2. It worked out of the box with the following configuration:
在尝试实现一个新的 Redis 容器来帮助我完成 Django 项目后,我使用了非常基本的配置来启动带有 Redis 7.2 的容器。它具有以下配置,开箱即用:
version: '3.8'
services:
cache:
image: redis:7.2-alpine
restart: always
ports:
- 6379:6379
command: redis-server --save 20 1 --loglevel warning
volumes:
- ./data/redis:/data
Copy snippet
Yet I was surprised that there was a warning mentioning something critical (at least not for the moment for me): warning overcommit_memory is set to 0! Background save may fail under low memory conditions. Being disabled can also cause failures without low memory conditions.
然而令我惊讶的是,有一个警告提到了一些关键的事情(至少目前对我来说不是):警告 overcommit_memory 设置为 0!在内存不足的情况下,后台保存可能会失败。在没有内存不足的情况下被禁用也可能导致故障。
The same warning provides a way to remove it, but in order to remove this warning properly in Docker, you will need to follow some extra steps as a default image won't be enough. In this tutorial, I will explain to you how to easily solve this warning in your Redis server containerized on Docker.
相同的警告提供了一种删除它的方法,但为了在 Docker 中正确删除此警告,您将需要执行一些额外的步骤,因为默认映像是不够的。在本教程中,我将向您解释如何在 Docker 上容器化的 Redis 服务器中轻松解决此警告。
1. Create an initialization script 1.创建初始化脚本
We need to tweak the kernel's memory overcommit handling in the container. When the vm.overcommit_memory
option is set to 1, the kernel will always allow memory allocation even if it doesn't have enough memory to cover the allocation. This setting is especially useful for applications that rely on being able to allocate more memory than is physically available (which is usually the case for most of the applications that use Redis).
我们需要调整容器中内核的内存过量使用处理。当vm.overcommit_memory
选项设置为 1 时,内核将始终允许内存分配,即使它没有足够的内存来覆盖分配。此设置对于依赖于能够分配比物理可用内存更多的内存的应用程序特别有用(大多数使用 Redis 的应用程序通常都是这种情况)。
In the case of our docker container, we can run a .sh
file to tweak this setting and start the Redis server as usual. Create the init.sh
script for Redis with the following content in your project:
对于我们的 docker 容器,我们可以运行.sh
文件来调整此设置并像往常一样启动 Redis 服务器。在项目中使用以下内容为 Redis 创建init.sh
脚本:
# 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.
# The overcommit_memory has 3 options.
# 0, the system kernel check if there is enough memory to be allocated to the process or not,
# if not enough, it will return errors to the process.
# 1, the system kernel is allowed to allocate the whole memory to the process
# no matter what the status of memory is.
# 2, the system kernel is allowed to allocate a memory whose size could be bigger than
# the sum of the size of physical memory and the size of exchange workspace to the process.
sysctl vm.overcommit_memory=1
# Start redis server
redis-server /usr/local/etc/redis/redis.conf --loglevel warning --bind 0.0.0.0
Copy snippet
Save the changes and continue with the next step.
保存更改并继续下一步。
2. Create a Redis configuration file 2.创建Redis配置文件
You need to have a configuration file with all the settings of Redis that you need. If you don't have any, you can visit the official Redis website here to get an example of the configuration file for each version. In my case, I'm going to use the default configuration file for Redis 7.2 from the official website and I'm going to store it in the redis.conf
and it will be stored in the root directory of my project.
您需要有一个配置文件,其中包含您需要的 Redis 的所有设置。如果您没有,可以访问Redis官方网站获取每个版本的配置文件示例。就我而言,我将使用官方网站上的 Redis 7.2 默认配置文件,并将其存储在redis.conf
中,并将其存储在我的项目的根目录中。
3. Create a Dockerfile for the Redis container 3. 为Redis容器创建Dockerfile
Instead of using a ready-to-use container of Redis, we need to start from the base image of Redis, in my case version 7.2, and will run some extra commands to copy the previously created redis.conf
and init.sh
files in the container and will allow the sh script to be executable:
我们需要从 Redis 的基础镜像(在我的例子中是版本 7.2)开始,而不是使用现成的 Redis 容器,并将运行一些额外的命令来复制之前创建的redis.conf
和init.sh
文件容器并将允许 sh 脚本可执行:
FROM redis:7.2-alpine
WORKDIR /redis
COPY redis.conf /usr/local/etc/redis/redis.conf
COPY init.sh ./
RUN chmod +x init.sh
Copy snippet
Save the changes to the file and continue with the next step.
保存对文件的更改并继续下一步。
4. Configure docker-compose.yml with the new custom Redis container 4. 使用新的自定义 Redis 容器配置 docker-compose.yml
The last thing we need to do is to adjust our container to be built using the Dockerfile we created and to start with a different entry point, which is going to be the init.sh
script. There is something important to note in this configuration besides the initialization script, and that's the privileged option that is set to true. This option is often used when a container needs to perform tasks that require elevated privileges, such as accessing devices or interacting with the kernel in ways that are not allowed by default, which is exactly what we need to adjust the overcommit_memory
option.
我们需要做的最后一件事是调整要使用我们创建的 Dockerfile 构建的容器,并从不同的入口点(即init.sh
脚本)开始。除了初始化脚本之外,此配置中还有一些重要事项需要注意,那就是设置为 true 的特权选项。当容器需要执行需要提升权限的任务时,通常会使用此选项,例如以默认不允许的方式访问设备或与内核交互,这正是我们需要调整overcommit_memory
选项的原因。
The docker-compose.yml
file with the Redis container will look similar to this:
带有 Redis 容器的docker-compose.yml
文件将类似于以下内容:
version: '3.8'
services:
cache:
# Adjust the build context to your needs targetting the created Dockerfile
build:
context: ./dockerfiles/redis
dockerfile: Dockerfile
image: redis:7.2-alpine
restart: always
ports:
- 6379:6379
# Run the init script
command: sh -c "./init.sh"
# Run as privileged to allow the container to change the vm.overcommit_memory setting
privileged: true
volumes:
- ./docker/data/redis:/data
Copy snippet
After adjusting the docker-compose.yml
file, restart, and rebuild your container:
调整docker-compose.yml
文件后,重新启动并重建容器:
docker compose up --build -d
Copy snippet
And you should see now that the container doesn't have this warning anymore:
现在您应该看到容器不再有此警告:
Happy coding ❤️!
快乐编码❤️!