大数据&云计算|大数据下的用户中心如何设计( 二 )


本文插图

但对于非uid属性上的查询 , 就悲剧了 , 例如login_name属性上的查询:
大数据&云计算|大数据下的用户中心如何设计
本文插图

假设访问login_name=shenjian的数据 , 由于不知道数据落在哪个库上 , 往往需要遍历所有库 , 当分库数量多起来 , 性能会显著降低 。
用户中心 , 非uid属性查询 , 有哪些业务场景?
任何脱离业务的架构设计都是耍流氓 。
在进行架构讨论之前 , 先来对业务进行简要分析 , 用户中心非uid属性上 , 有两类典型的业务需求 。
第一大类 , 用户侧 , 前台访问 , 最典型的有两类需求:

(1)用户登录:通过登录名login_name查询用户的实体 , 1%请求属于这种类型;
(2)用户信息查询:登录之后 , 通过uid来查询用户的实例 , 99%请求属这种类型;
用户侧的查询 , 基本上是单条记录的查询 , 访问量较大 , 服务需要高可用 , 并且对一致性的要求较高 。
第二大类 , 运营侧 , 后台访问 , 根据产品、运营需求 , 访问模式各异 , 按照年龄、性别、头像、登陆时间、注册时间来进行查询 。
运营侧的查询 , 基本上是批量分页的查询 , 由于是内部系统 , 访问量很低 , 对可用性的要求不高 , 对一致性的要求也没这么严格 。
对于这两类不同的业务需求 , 应该使用什么样的架构方案来解决呢?
总的来说 , 针对这两类业务需求 , 架构设计的核心思路为:
(1)用户侧 , 采用“建立非uid属性到uid的映射关系”的架构方案;
(2)运营侧 , 采用“前台与后台分离”的架构方案;
用户侧 , 如何实施“建立非uid属性到uid的映射关系”呢?
常见的方法有四种:
(1)索引表法;
(2)缓存映射法;
(3)生成uid法;
(4)基因法;
接下来 , 咱们一一介绍 。
什么是 , 索引表法?

索引表法的思路是:uid能直接定位到库 , login_name不能直接定位到库 , 如果通过login_name能查询到uid , 问题便能得到解决 。
具体的解决方案如下:
(1)建立一个索引表记录login_name与uid的映射关系;
(2)用login_name来访问时 , 先通过索引表查询到uid , 再通过uid定位相应的库;
(3)索引表属性较少 , 可以容纳非常多数据 , 一般不需要分库;
(4)如果数据量过大 , 可以通过login_name来分库;
索引表法 , 有什么缺点呢?
数据访问 , 会增加一次数据库查询 , 性能会有所下降 。
什么是 , 缓存映射法?
缓存映射法的思路是:访问索引表性能较低 , 把映射关系放在缓存里 , 能够提升性能 。
具体的解决方案如下:
(1)login_name查询先到cache中查询uid , 再根据uid定位数据库;
(2)假设cache miss , 扫描所有分库 , 获取login_name对应的uid , 放入cache;
(3)login_name到uid的映射关系不会变化 , 映射关系一旦放入缓存 , 不会更改 , 无需淘汰 , 缓存命中率超高;
(4)如果数据量过大 , 可以通过login_name进行cache水平切分;
缓存映射法 , 有什么缺点呢?
仍然多了一次网络交互 , 即一次cache查询 。
什么是 , 生成uid法?

生成uid法的思路是:不进行远程查询 , 由login_name直接得到uid 。
具体的解决方案如下:
(1)在用户注册时 , 设计函数login_name生成uid , uid=f(login_name) , 按uid分库插入数据;
(2)用login_name来访问时 , 先通过函数计算出uid , 即uid=f(login_name)再来一遍 , 由uid路由到对应库;
生成uid法 , 有什么缺点呢?


推荐阅读