dot Redis 8 来了——而且是开源的

了解更多

8.1.1 用户信息

返回首页

8.1.1 用户信息

在各种在线服务和社交网络中,用户对象可以是构成一切的基本构建块。 我们的 Twitter 仿制品也不例外。

图 8.1 存储在 HASH 中的示例用户信息

我们将用户的信息存储在 Redis 中,作为 HASH,类似于我们在第 1 章中存储文章的方式。我们将存储的数据包括用户的用户名、他们有多少粉丝、他们关注了多少人、他们发布了多少状态消息、他们的注册日期以及我们决定在线存储的任何其他元信息。 图 8.1 显示了一个示例 HASH,其中包含用户名为 dr_josiah(我的 Twitter 用户名)的用户的信息。

从这张图中,你可以看到我拥有相当数量的粉丝,以及其他信息。 当一个新用户注册时,我们只需要创建一个对象,将 following、followers 和 post count 设置为零,为注册时间设置一个新的时间戳,以及相关的用户名。 执行此初始创建的函数如下所示。

清单 8.1 如何创建一个新的用户配置文件 HASH
def create_user(conn, login, name):
    llogin = login.lower()
 
    lock = acquire_lock_with_timeout(conn, 'user:' + llogin, 1)

尝试获取登录名小写版本的锁。 此函数在第 6 章中定义。

    if not lock:
        return None

如果我们无法获得锁,则其他人已经拥有相同的登录名。

 
    if conn.hget('users:', llogin):
        return None

我们还存储了一个登录名小写形式到用户 ID 的 HASH,因此如果已经存在一个登录名映射到一个 ID,我们就知道并且不会将其提供给第二个人。

 
    id = conn.incr('user:id:')

每个用户都会获得一个唯一的 ID,该 ID 通过递增计数器生成。

    pipeline = conn.pipeline(True)
 
    pipeline.hset('users:', llogin, id)

将小写的登录名添加到从登录名到用户 ID 的 HASH。

    pipeline.hmset('user:%s'%id, {
        'login': login,
        'id': id,
        'name': name,
        'followers': 0,
        'following': 0,
        'posts': 0,
        'signup': time.time(),

将用户信息添加到用户的 HASH。

    })
 
    pipeline.execute()
 
    release_lock(conn, 'user:' + llogin, lock)

释放登录名上的锁。

    return id

返回用户的 ID。

在我们的函数中,我们执行预期的用户 HASH 中初始用户信息的设置,但我们还获取用户登录名周围的锁。 这个锁是必要的:它保证我们不会有两个请求同时尝试创建具有相同登录名的用户。 锁定后,我们验证登录名是否已被其他用户占用。 如果该名称尚未被占用,我们将为用户生成一个新的唯一 ID,将登录名添加到登录名到用户 ID 的映射中,然后创建用户的 HASH

敏感用户信息由于用户 HASH 将被无数次地获取以用于呈现模板,或直接作为 API 请求的响应返回,因此我们不会在此 HASH 中存储敏感的用户信息。 目前,我们假设 HASHed 密码、电子邮件地址等存储在其他键中,或完全存储在不同的数据库中。

我们已经完成了创建用户并设置了所有必要的关于他们的元信息。 从这里开始,构建我们的 Twitter 仿制品的下一步是状态消息本身。