Redis 因内存不足而中止
Redis aborting for OUT OF MEMORY
我正在尝试将一个大文件(电影)分块移动到 redis 缓存中。
我在 Windows 框上使用 stackexchange.redis。
redis 配置为执行 allkey-lru 并每秒使用 append。 Maxmemory 配置为 100mb。
ConnectionMultiplexer redis2 = ConnectionMultiplexer.Connect("localhost:6380, syncTimeout=100000");
IDatabase db2 = redis2.GetDatabase();
const int chunkSize = 4096;
string fileName = "D:\movie.mp4";
using (var file = File.OpenRead(fileName))
{
int bytesRead;
int inCounter = 1;
var buffer = new byte[chunkSize];
while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0)
{
db2.StringSet(file.Name + inCounter, buffer);
inCounter++;
}
}
当块大小为 chunkSize = 4096 时一切正常。
但是,当我将块大小更改为 65536 时,服务器崩溃并显示以下日志:
[2816] 20 Jul 23:06:42.300 * Starting automatic rewriting of AOF on 6766592700% growth
[2816] 20 Jul 23:06:42.331 * Background append only file rewriting started by pid 3672
[3672] 20 Jul 23:06:42.331 # Write error writing append only file on disk: Invalid argument
[3672] 20 Jul 23:06:42.331 # rewriteAppendOnlyFile failed in qfork: Invalid argument
[2816] 20 Jul 23:06:42.440 # fork operation complete
[2816] 20 Jul 23:06:42.440 # Background AOF rewrite terminated with error
[2816] 20 Jul 23:06:42.549 * Starting automatic rewriting of AOF on 7232582200% growth
[2816] 20 Jul 23:06:42.581 * Background append only file rewriting started by pid 1440
[2816] 20 Jul 23:06:42.581 # Out Of Memory allocating 10485768 bytes!
[2816] 20 Jul 23:06:42.581 #
=== REDIS BUG REPORT START: Cut & paste starting from here ===
[2816] 20 Jul 23:06:42.581 # ------------------------------------------------
[2816] 20 Jul 23:06:42.581 # !!! Software Failure. Press left mouse button to continue
[2816] 20 Jul 23:06:42.581 # Guru Meditation: "Redis aborting for OUT OF MEMORY" #..\src\redis.c:3467
[2816] 20 Jul 23:06:42.581 # ------------------------------------------------
[1440] 20 Jul 23:06:42.581 # Write error writing append only file on disk: Invalid argument
[1440] 20 Jul 23:06:42.581 # rewriteAppendOnlyFile failed in qfork: Invalid argument
有什么想法吗?
原来是一个非常有趣和令人惊讶的问题!
真正的原因是他们使用的分配器中存在内存碎片 (dlmalloc
)。
希望 MSFT 会做得更好,但我预计这需要一些时间。
同时,解决方法。
解决这个问题的正确方法(目前)
同时配置 maxmemory
和 maxheap
参数。使 maxheap
比 maxmemory
.
大得多
因此,如果您想要 maxmemory=100MB
,则将 maxheap
放大 5 倍甚至 10 倍,例如 maxheap=500MB
甚至 maxheap=1000MB
。
我不认为有什么好的经验法则 maxheap
需要多大,这就是为什么它是一个如此棘手的问题。
这样做的效果:Redis 仍然会尝试将内存使用量保持在 100MB
以下,但实际使用的物理内存可能
比那个大,可能高达 maxheap
值。具体多少取决于碎片化程度。希望
在现实生活中,这将保持在合理的水平。
我已将问题记录在团队中。 https://github.com/MSOpenTech/redis/issues/274
编辑:我根据新知识完全修改了这个答案。在编辑历史中查看以前的版本。
使用此命令设置最大堆大小肯定有效
redis-server redis.windows.conf –-maxheap 1gb
我正在尝试将一个大文件(电影)分块移动到 redis 缓存中。 我在 Windows 框上使用 stackexchange.redis。 redis 配置为执行 allkey-lru 并每秒使用 append。 Maxmemory 配置为 100mb。
ConnectionMultiplexer redis2 = ConnectionMultiplexer.Connect("localhost:6380, syncTimeout=100000");
IDatabase db2 = redis2.GetDatabase();
const int chunkSize = 4096;
string fileName = "D:\movie.mp4";
using (var file = File.OpenRead(fileName))
{
int bytesRead;
int inCounter = 1;
var buffer = new byte[chunkSize];
while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0)
{
db2.StringSet(file.Name + inCounter, buffer);
inCounter++;
}
}
当块大小为 chunkSize = 4096 时一切正常。 但是,当我将块大小更改为 65536 时,服务器崩溃并显示以下日志:
[2816] 20 Jul 23:06:42.300 * Starting automatic rewriting of AOF on 6766592700% growth
[2816] 20 Jul 23:06:42.331 * Background append only file rewriting started by pid 3672
[3672] 20 Jul 23:06:42.331 # Write error writing append only file on disk: Invalid argument
[3672] 20 Jul 23:06:42.331 # rewriteAppendOnlyFile failed in qfork: Invalid argument
[2816] 20 Jul 23:06:42.440 # fork operation complete
[2816] 20 Jul 23:06:42.440 # Background AOF rewrite terminated with error
[2816] 20 Jul 23:06:42.549 * Starting automatic rewriting of AOF on 7232582200% growth
[2816] 20 Jul 23:06:42.581 * Background append only file rewriting started by pid 1440
[2816] 20 Jul 23:06:42.581 # Out Of Memory allocating 10485768 bytes!
[2816] 20 Jul 23:06:42.581 #
=== REDIS BUG REPORT START: Cut & paste starting from here ===
[2816] 20 Jul 23:06:42.581 # ------------------------------------------------
[2816] 20 Jul 23:06:42.581 # !!! Software Failure. Press left mouse button to continue
[2816] 20 Jul 23:06:42.581 # Guru Meditation: "Redis aborting for OUT OF MEMORY" #..\src\redis.c:3467
[2816] 20 Jul 23:06:42.581 # ------------------------------------------------
[1440] 20 Jul 23:06:42.581 # Write error writing append only file on disk: Invalid argument
[1440] 20 Jul 23:06:42.581 # rewriteAppendOnlyFile failed in qfork: Invalid argument
有什么想法吗?
原来是一个非常有趣和令人惊讶的问题!
真正的原因是他们使用的分配器中存在内存碎片 (dlmalloc
)。
希望 MSFT 会做得更好,但我预计这需要一些时间。
同时,解决方法。
解决这个问题的正确方法(目前)
同时配置 maxmemory
和 maxheap
参数。使 maxheap
比 maxmemory
.
因此,如果您想要 maxmemory=100MB
,则将 maxheap
放大 5 倍甚至 10 倍,例如 maxheap=500MB
甚至 maxheap=1000MB
。
我不认为有什么好的经验法则 maxheap
需要多大,这就是为什么它是一个如此棘手的问题。
这样做的效果:Redis 仍然会尝试将内存使用量保持在 100MB
以下,但实际使用的物理内存可能
比那个大,可能高达 maxheap
值。具体多少取决于碎片化程度。希望
在现实生活中,这将保持在合理的水平。
我已将问题记录在团队中。 https://github.com/MSOpenTech/redis/issues/274
编辑:我根据新知识完全修改了这个答案。在编辑历史中查看以前的版本。
使用此命令设置最大堆大小肯定有效
redis-server redis.windows.conf –-maxheap 1gb