文章目录
如何设计一个会议室预定系统?
如何设计一个计数服务?
- MYSQL 直接存储计数值
- 数据量大之后,分库分表
- 流量更大后,就需要 Redis 来加速,协助处理请求(自然就会引来DB与缓存不一致的情况 解决)
- 如何提升写的能力?批量,异步
- 如何缩减存储成本?冷热分离,改造 Redis 底层数据
如何设计一个高性能短链系统?
哈希算法
- 哈希 MurmurHash 算法, MD5,SHA
- 进制转换
- 长链 和 短链的映射关系存储,以短链为唯一索引,写入时,判断是否成功,如果不成功,就在长链的基础上加上自定义字符串,计算 Hash,存储 MYSQL
- (注:
布隆过滤器
是一种非常省内存的数据结构,长度为 10 亿的布隆过滤器,只需要 125 M 的内存空间)用所有生成的短网址构建布隆过滤器,当一个新的长链生成短链后,先将此短链在布隆过滤器中进行查找,如果不存在,说明 db 里不存在此短网址,可以插入!
全局唯一自增序列算法
见下面 如何实现全局唯一ID 即可
如果让你写一个消息队列,该如何进行架构设计?
关键点
(1)首先这个 mq 得支持可伸缩性吧,就是需要的时候快速扩容,就可以增加吞吐量和容量,那怎么搞?设计个分布式的系统呗,参照一下 kafka 的设计理念,broker -> topic -> partition,每个 partition 放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给 topic 增加 partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了?
(2)
其次你得考虑一下这个 mq 的数据要不要落地磁盘吧?那肯定要了,落磁盘才能保证别进程挂了数据就丢了。那落磁盘的时候怎么落啊?顺序写,这样就没有磁盘随机读写的寻址开销,磁盘顺序读写的性能是很高的,这就是 kafka 的思路。
(Kafka 就是充分利用了磁盘的这个特性。它的存储设计非常简单,对于每个分区,它把从 Producer 收到的消息,顺序地写入对应的 log 文件中,一个文件写满了,就开启一个新的文件这样顺序写下去。消费的时候,也是从某个全局的位置开始,也就是某一个 log 文件中的某个位置开始,顺序地把消息读出来)
(3)其次你考虑一下你的 mq 的可用性啊?这个事儿,具体参考之前可用性那个环节讲解的 kafka 的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务
如何幂等性?
在计算机中编程中,一个幂等操作的特点是其
任意多次执行所产生的影响均与一次执行的影响相同
1.使用数据库唯一主键索引实现幂等性
2.乐观锁实现幂等性
3.Token 令牌如何实现幂等性
所谓的 token 令牌其实就是为了防止用户重复提交一个表单信息,这一点基本上 PHP 的框架都会带有 token 验证。服务端需要生成一个全局唯一的 id,(例如:snowflake 雪花算法,美团 Leaf 算法,滴滴 TinyID 算法,百度 Uidgenerator 算法,uuid,redis 等)。
- 客户端每次进入表单页面可以优先申请一个唯一令牌存储本地,服务端存储令牌 token 值(redis,文件,memcache 都可)
- 每次发送请求时可以在 Headers 头部中带上当前这个 token 令牌
- 服务端验证 token 是否存在,存在则删除 token,执行后续业务逻辑;不存在则响应客户端重复提交提示语
如何实现全局唯一ID?
数据库自增ID
UUID 的生成
核心思想:结合机器的网卡(基于名字空间/名字的散列值MD5/SHA1)、当地时间(基于时间戳&时钟序列)、一个随记数来生成UUID。
雪花算法(snowflake)
核心思想:把 64-bit 分别划分成多段,分开来标示机器、时间、某一并发序列等,从而使每台机器及同一机器生成的ID都是互不相同
如何解决:时钟回拨(我的想法是添加随机数)