第一节课
Q:请你思考一下,用户邀请其他用户注册的记录,属于历史记录还是关系记录?
A:用户邀请其他用户注册的记录,我认为属于关系记录。
虽然这种记录有历史记录特征,但是被邀请注册的用户只能被邀请一次,所以总量是可控的。同时,这种表的用途很明确,表内记录的是关系记录,查询时会按邀请人或被邀请人uid进行查询。
留言区里也有不少精彩的答案,推荐你去看看。比如@移横为固的答案,这里我也复制过来:
一开始觉得注册邀请表应该作为历史表。思考了下作为关系表也是可以的。
在满足下面的注册邀请前提下:
1.邀请人用类似二维码分享方式,注册人主动扫码注册(不使用点对点邀请,被邀请人可能不接受)。
2.只能注册成功一次。-
这样每一条邀请记录都是一个用户的注册记录:可以定义如下字段:(邀请者,注册人,注册时间,邀请方式)。-
表的字段结构都非常简单,记录的总量最多就是账号量,并不会随时间不断膨胀。因此可以胜任关系表的查询需求。
在实际项目中,我们会遇到很多类似情况,需要我们预防超出预期的操作,核心在于我们怎么约束使用表的人,以及我们要怎么用表里的数据。
第二节课
Q1:使用BloomFilter识别热点key时,有时会识别失误,进而导致数据没有找到,那么如何避免这种情况呢?
A1:有一个特殊方法能降低概率,原始key通过BloomFilter 检测一次,md5后再通过另外一个BloomFilter再测一次。
Q2:使用BloomFilter只能添加新key,不能删除某一个key,如果想更好地更新维护,有什么其他方式吗?
A2:请参考Redis的Cuckoo Filter的实现。
第三节课
Q:用户如果更换了昵称,如何快速更换token中保存的用户昵称呢?
A:在更换用户昵称,同时更换修改端的token。如果我们的用户有多个客户端,那么可以利用缓存更新提及的Version版本号,让客户端定期检测判断token是否需要更换。
对于这个问题,置顶留言里@徐曙辉同学的回答也很有趣:
如果我来做快速更换昵称的功能,有两种方式:
a.在用户修改昵称后,内存中加入一个用户标识,解析token后读取该标识,有则返回特定code,让客户端重新拿token。甚至可以不用客户端参与,返回301重定向到获取新token的路由。
b. token里面不存用户信息,只存用户ID,需要用户信息的时候从缓存读。
徐同学的第一个解法很暴力,但是很有趣。
第二个方式也很有意思,这里我也补一个应用技巧:我们可以通过设定固定网址 user/用户uid/heaer.jpg方式,直接获取用户头像,这样也不用考虑更新问题了。
围绕着我的补充,这个话题还有后续讨论,我也一并展示出来,仍然是徐同学的回答:
这样确定是占了额外的存储空间,优点是不用查DB和缓存,减少它们的压力,在Web应用中,用户信息读取挺频繁。
我认为这个思路很优秀,建议尽量使用对象存储做。关于对象存储的话题,你还可以参考第二十一节课的内容,我在里面详细分享了对象存储如何管理小文件和大文本。
第四节课
Q:如果 Otter 同步的链路是环形的,那么如何保证数据不会一直循环同步下去?
A:Otter在事务头尾插入同步标识,解析时会通过这个方式防止发起方再执行同样事务。
第八节课
Q:用什么方法能够周期检查出两个系统之间不同步的数据?
A:在数据上增加修改时间或版本号,每次更新的时候同步更新版本号,通过版本号能够很好地帮助我们识别哪个数据是最新的。
我们再看看@LecKeyt同学的回答:
每条数据都有唯一的数据标识(一般是自增id,或者有规律一串数字唯一id),而且一般都是小到大,根据这个最大值应该就能判断出来。如果数据不同步应该找到对应数据节点做补偿操作。
看到他的回答后,我又追加了一个提问“如何避免更新操作同一条数据”?你也可以自行思考一下,再继续往下看。
后面的回答同样来自@LecKeyt同学:
更新带来的数据不一致的情况,我个人认为要看具体业务,如果是实时性要求不高的可以用事件队列处理,如果要求强一致性那最好的方式应该是分布式事务保证了。
第九节课
Q:现在市面上有诸多分布式实现方式,你觉得哪一种性能更好?
A:建议考虑使用AT或Seata方式。
以上就是用户中心和电商系统这两个章节的思考题答案,希望能带给你一些启发。接下来,老师还会针对剩余的课后思考题,以及你的提问来作出解答。有任何问题,还是跟以前一样,欢迎你在留言区多多互动。