关于redis备份的一个问题

请教一个问题,就是redis备份的话,是把所有从redis服务器启动开始,把所有的数据都做备份,还是只备份近期的数据?还有就是mysql和redis之间,哪些需要备份到mysql里,查询redis没有,从mysql里拿并写入redis?

Redis备份的策略,可以根据需求来决定备份全量数据还是只备份近期数据。
根据业务需求和数据特征,可以选择性地将数据从MySQL备份到Redis,或从MySQL中读取并更新到Redis中,以满足数据持久化和缓存的需求,并确保数据的完整性和可用性。

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7430602
  • 这篇博客也不错, 你可以看下利用redis缓存mysql查询结果,关于缓存命名
  • 除此之外, 这篇博客: redis与数据库的数据一致性问题中的 如何保障mysql和redis之间的数据一致性? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 1.强一致(向数据库插入一条数据时,同时向redis中也插入一条数据)

    2.定时任务:设置过期时间

    结合实际场景,解决redis和mysql的数据一致性
    在并发不高的情况下:读操作优先读取redis,不存在的话就去访问MySQL数据库,并把从数据库中读到的数据写回Redis中;写操作的话,直接写MySQL,成功后再写入Redis(可以在MySQL数据库业务代码中定义CRUD触发器,在触发CRUD操作后写数据到Redis,也可以在Redis端解析mysql的binlog,再做相应的操作)。
    在并发高的情况下:读操作和上面一样,写操作是异步写,写入Redis后直接返回,然后定时定期写入MySQL。或者用MQ异步将mysql数据同步到redis。
    场景一:
    问题:当更新数据时,如更新某商品的库存,当前商品的数据库存是100、缓存存的是100,现在都要更新为99,先更新数据库更改成99,然后删除缓存,如果删除缓存失败了,这意味着数据库存的是99,而缓存还是100,这就导致数据库和缓存的数据不一致。(加一个1/0在mysql和redis之间)

    解决方法:
    这种情况应该是先删除缓存,然后在更新数据库。如果删除缓存失败,那就不要更新数据库。如果说删除缓存成功,而更新数据库失败了,那查询的时候只是从数据库里查了旧的数据而已,这样就能保持数据库与缓存的一致性。

    场景二
    问题:在高并发的情况下,如果当删除完缓存的时候,这时去更新数据库,但还没有更新完,另外一个请求来查询数据,发现缓存里没有,就去数据库里查,还是以上面商品库存为例,如果数据库中产品的库存是100,那么查询到的库存是100,然后插入缓存,插入完缓存后,原来那个更新数据库的线程把数据库更新为了99,导致数据库与缓存数据不一致的情况。(缓存中是脏数据)

    解决方法:
    遇到这种情况,可以用第三方MQ队列去解决这个问题,创建几个队列,如20个,根据商品的ID去做hash值,然后对队列个数取摸,当有数据更新请求时,先把它丢到队列里去,当更新完后在从队列里去除,如果在更新的过程中,遇到以上场景,先去缓存里看下有没有数据,如果没有,可以先去队列里看是否有相同商品ID在做更新,如果有也把查询的请求发送到队列里去,然后同步等待缓存更新完成。
    这里有一个优化点,如果发现队列里有一个查询请求了,那么就不要放新的查询操作进去了,用一个while(true)循环去查询缓存,循环个200MS左右,如果缓存里还没有则直接取数据库的旧数据,一般情况下是可以取到的。

  • 您还可以看一下 尹成老师的go数据库mysql与redis课程中的 redis作为二级缓存基本思路说明小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    问题1:在进行redis备份时,是需要备份从redis服务器启动开始到现在的所有数据,还是只备份近期的数据?

    回答1:在进行redis备份时,可以选择备份从redis服务器启动开始到现在的所有数据,也可以选择只备份近期的数据。这取决于您对备份策略的需求和存储资源的限制。

    如果您选择备份从redis服务器启动开始到现在的所有数据,您可以使用Redis的持久化功能,通过将数据写入到磁盘上的RDB文件或AOF文件来实现。RDB文件是一个紧凑的二进制文件,它可以定期创建快照并保存redis服务器在某个时间点的所有数据。AOF文件是一个追加写日志文件,它将每个写操作追加到文件中,以便在服务器重启时可以重新构建数据。

    如果您只想备份近期的数据,您可以使用Redis的复制功能来实现。复制将整个redis数据库的所有数据从主服务器复制到一个或多个从服务器。在进行备份之前,您可以通过执行命令BGSAVE来触发主服务器的RDB持久化操作,这样从服务器将会将主服务器的数据进行复制。复制期间,从服务器将持续地接收并复制主服务器的数据更新。

    问题2:在mysql和redis之间,有哪些数据需要备份到mysql中,而不需要在redis中查询,需要从mysql中获取并写入redis中呢?

    回答2:在mysql和redis之间,通常需要备份到mysql中的数据是那些不适合或无法存储在redis中的数据。这些数据可能需要进行持久化存储、事务管理或复杂查询等操作。

    一些常见的需要备份到mysql中的数据可以包括用户信息、订单信息、配置信息、日志信息等。这些数据通常需要在redis中查询的话会增加复杂性或性能开销,并且可能需要进行持久化存储或更严格的事务管理。

    具体的备份流程可以根据应用的需求和复杂性进行设计。一种常见的做法是,在数据更新时,先将数据写入mysql中,然后再更新到redis中。这可以通过使用分布式事务或消息队列等技术来实现数据的一致性。

    以下是一个示例代码,演示了如何在数据更新时备份到mysql中并同步到redis中:

    import redis
    import mysql.connector
    
    # 连接到redis服务器
    redis_client = redis.Redis(host='localhost', port=6379)
    
    # 连接到mysql服务器
    mysql_connection = mysql.connector.connect(
      host="localhost",
      user="yourusername",
      password="yourpassword",
      database="yourdatabase"
    )
    
    # 执行数据更新操作
    def update_data(key, value):
        # 更新mysql中的数据
        mysql_cursor = mysql_connection.cursor()
        sql = "UPDATE yourtable SET yourcolumn = %s WHERE yourkey = %s"
        val = (value, key)
        mysql_cursor.execute(sql, val)
        mysql_connection.commit()
    
        # 更新redis中的数据
        redis_client.set(key, value)
    
    # 备份数据到mysql中并同步到redis中
    def backup_to_mysql_and_sync_to_redis(key):
        # 从mysql中获取数据
        mysql_cursor = mysql_connection.cursor()
        sql = "SELECT yourcolumn FROM yourtable WHERE yourkey = %s"
        val = (key,)
        mysql_cursor.execute(sql, val)
        result = mysql_cursor.fetchone()
    
        # 将数据写入redis中
        if result:
            redis_client.set(key, result[0])
    
    # 查询数据时,先从redis中查询,如果不存在再从mysql中查询并写入redis
    def get_data(key):
        value = redis_client.get(key)
        if value:
            return value
        else:
            backup_to_mysql_and_sync_to_redis(key)
            value = redis_client.get(key)
            return value
    

    请注意,上述代码仅为示例,具体的实现方式可能会因应用需求的不同而有所调整。