10

使用 SWAPDB 命令在线替换 Redis 数据库 — blog.huangz.me

 3 years ago
source link: https://blog.huangz.me/2019/redis-online-swap-db.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用 SWAPDB 命令在线替换 Redis 数据库

本文摘录自《Redis使用手册》, 更多信息请见: RedisGuide.com

../_images/redisguide.png

正如上一节所说, SWAPDB 命令可以以非阻塞方式互换给定的两个数据库。 因为这个命令的执行速度是如此之快, 并且完全不会阻塞服务器, 所以用户实际上可以使用这个命令来实行在线的数据库替换操作。

举个例子, 假设我们拥有一个 Redis 服务器, 它的 0 号数据库储存了用户的邮件地址以及经过加密的用户密码, 这些数据可以用于登录用户账号。 不幸的是, 因为一次漏洞事故, 这个服务器遭到了黑客入侵, 并且经过确认, 这个服务器储存的所有用户密码均已泄露。 为了保障用户的信息安全, 我们决定立即重置所有用户密码, 具体的做法是: 遍历所有用户的个人档案, 为每个用户生成一个新的随机密码, 并使用这个新密码替换已经泄露的旧密码。

代码清单 11-4 展示了一个用于重置用户密码的脚本, 它的 reset_user_password() 函数会迭代 origin 数据库中的所有用户数据, 为他们生成新密码, 并将更新后的用户信息储存到 new 数据库里面。 在此之后, 函数会使用 SWAPDB 命令互换新旧两个数据库, 并以异步方式移除旧数据库。


代码清单 11-4 用于重置用户密码的脚本代码:/database/reset_user_password.py

import random

from redis import Redis
from hashlib import sha256

def generate_new_password():
    random_string = str(random.getrandbits(256)).encode('utf-8')
    return sha256(random_string).hexdigest()

def reset_user_password(origin, new):
    # 两个客户端,分别连接两个数据库
    origin_db = Redis(db=origin)
    new_db = Redis(db=new)

    for key in origin_db.scan_iter(match="user::*"):
        # 从源数据库获取现有用户信息
        user_data = origin_db.hgetall(key)
        # 重置用户密码
        user_data["password"] = generate_new_password()
        # 将新的用户信息储存到新数据库里面
        new_db.hmset(key, user_data)

    # 互换新旧数据库
    origin_db.swapdb(origin, new)

    # 以异步方式移除旧数据库
    # (new_db 变量现在已经指向旧数据库)
    new_db.flushdb(asynchronous=True)

作为例子, 表 11-5 和表 11-6 分别展示了设置新密码之前和之后的用户数据。 注意, 为了凸显新旧密码之间的区别, 重置之前的用户密码是未经加密的。


表 11-5 重置之前的用户数据

email 字段(邮箱地址)

password 字段(未加密密码)

“user::54209”

[email protected]

“petergogo128”

“user::73914”

[email protected]

“happyjack256”

“user::98321”

[email protected]

“tomrocktheworld512”

“user::39281”

[email protected]

“maryisthebest1024”


表 11-6 重置之后的用户数据

email 字段(邮箱地址)

password 字段(已加密密码)

“user::54209”

[email protected]

“669a533168e4da2fce34…4d2af”

“user::73914”

[email protected]

“e0caf7fc1245fa13fb34…a18eb”

“user::98321”

[email protected]

“1b9f3944bec47bed3527…388c1”

“user::39281”

[email protected]

“b7f6e3cd4ca27ac67851…75ccf”


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK