• redis RDB快照失败导致redis命令执行错误


    概述

    • 问题
    • 解决

    问题

    环境:window10 内存16G 4核
    场景:使用redis存储一些高并发读写的数据,并发测试的时候偶发RDB快照失败,导致redis命令无法执行。

    客户端报错:

    MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk.Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.

    根据该报错我们去找redis server的日志详细了解关于这个RDB error(当时我的redis是装在自己电脑上的,默认情况下redis log文件在redis安装文件的根级目录下,和redis-server.exe一个目录,redis-server.log)

    === REDIS BUG REPORT START: Cut & paste starting from here ===
    Redis version: 5.0.9
    [16668] 16 Oct 20:52:03.200 # --- EXCEPTION_ACCESS_VIOLATION
    [16668] 16 Oct 20:52:03.201 # --- STACK TRACE
    redis-server.exe!StackTraceInfo(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:153)(0x14018CBB0, 0x0014FF60, 0x1400DD020, 0x0014DF00)
    redis-server.exe!UnhandledExceptiontHandler(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x0014DF00, 0x1400DD001, 0x00000000, 0x7FCD35004F57)
    KERNELBASE.dll!UnhandledExceptionFilter(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x00000000, 0x7FF996AC43B8, 0x00000000, 0x0014FEF0)
    ntdll.dll!memset(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x00000000, 0x00000000, 0x0014E4C8, 0x0014E550)
    ntdll.dll!_C_specific_handler(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x00000000, 0x0014E4B0, 0x0014EB70, 0x0014EB70)
    ntdll.dll!_chkstk(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x00000001, 0x7FF996980000, 0x00000000, 0x7FF996AEE9E4)
    ntdll.dll!RtlRaiseException(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x00000000, 0x00000000, 0x0001D389, 0x00000000)
    ntdll.dll!KiUserExceptionDispatcher(D:devGitHub edissrcWin32_InteropWin32_StackTrace.cpp:186)(0x7FCD29C28850, 0x41D7E265DC800000, 0x00148563, 0x0001D36E)
    redis-server.exe!rdbSaveObject(D:devGitHub edissrc db.c:869)(0x00000001, 0x140048105, 0x00000009, 0x0014F1F0)
    redis-server.exe!rdbSaveKeyValuePair(D:devGitHub edissrc db.c:1072)(0x0014F1F0, 0x00000000, 0x06C00000, 0x00000009)
    redis-server.exe!rdbSaveRio(D:devGitHub edissrc db.c:1216)(0x018BDDC0, 0x00DC0000, 0x00000000, 0x0000411C)
    redis-server.exe!rdbSave(D:devGitHub edissrc db.c:1318)(0x02098A08, 0x00DC0000, 0x00DC0000, 0x0000009D)
    redis-server.exe!QForkChildInit(D:devGitHub edissrcWin32_InteropWin32_QFork.cpp:297)(0x00000210, 0x00000000, 0x00000210, 0x0045F4D0)
    redis-server.exe!main(D:devGitHub edissrcWin32_InteropWin32_QFork.cpp:1136)(0x00000000, 0x00000000, 0x004450D0, 0x00000000)
    redis-server.exe!__scrt_common_main_seh(d:agent_work4ssrcvctoolscrtvcstartupsrcstartupexe_common.inl:288)(0x00000000, 0x00000000, 0x00000000, 0x00000000)
    KERNEL32.DLL!BaseThreadInitThunk(d:agent_work4ssrcvctoolscrtvcstartupsrcstartupexe_common.inl:288)(0x00000000, 0x00000000, 0x00000000, 0x00000000)
    ntdll.dll!RtlUserThreadStart(d:agent_work4ssrcvctoolscrtvcstartupsrcstartupexe_common.inl:288)(0x00000000, 0x00000000, 0x00000000, 0x00000000)
    ntdll.dll!RtlUserThreadStart(d:agent_work4ssrcvctoolscrtvcstartupsrcstartupexe_common.inl:288)(0x00000000, 0x00000000, 0x00000000, 0x00000000)

    解决

    通过日志我们可以知道这是因为RDB快照失败导致的命令无法执行,在redis中我们可以设置忽略这个错误,即快照失败依然可以进行执行命令。

    redis配置项中关于这个的配置项名称为stop-writes-on-bgsave-error,默认值为yes,我们需要改为no。
    可以直接在client上执行命令:

    config set stop-writes-on-bgsave-error no
    

    这个修改是一次性的,只会修改redis当前运行的内存中的配置项的值,如果需要永久修改我们需要在redis配置文件redis.conf中修改stop-writes-on-bgsave-error的值。

    解决RDB快照失败:

    原因

    一:快照文件当前登录用户无写权限
    二:磁盘空间不足
    三:因为bgsave需要fork一个子进程,如果内存不足以fork子进程的话也会报错

    根据以上三个原因的解决方案有:

    一:设置快照文件的写权限
    二:清理磁盘空间
    三:清理内存或者设置系统参数允许放行fork子进程当内存不足的时候,在linux内核中的vm.overcommit_memory参数(window暂时不知道怎么改)

    如果 vm.overcommit_memory = 1,直接放行
    vm.overcommit_memory = 0:则比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行。
    vm.overcommit_memory = 2:则会比较 进程所有已分配的虚拟内存加上此次请求分配的虚拟内存和系统当前的空闲物理内存加上swap,决定是否放行。

  • 相关阅读:
    static作用(修饰函数、局部变量、全局变量)(转)
    地弹
    开漏(open drain)和开集(open colletor)
    过冲、振铃,非单调性
    串扰(crosstalk)
    数字通信基本概念
    电源和地
    分布式系统与集总系统
    传输线及其特性阻抗
    MSP430G2553 Launchpad 硬件I2C驱动
  • 原文地址:https://www.cnblogs.com/prelude1214/p/13861563.html
Copyright © 2020-2023  润新知