1.如何设计一个分布式的流控组件
可以使用redis结合lua脚本的原子性去实现;采取令牌桶算法作为限流方式,redis存储桶容量、当前token数量、token生成速率和上一次更新时间,每次有请求的时候就使用lua脚本,判断当前token数目、然后扣减并返回结果。
2.高并发系统设计
首先是使用消息队列对任务进行缓存;使用分库分表的方式降低压力,使用rpc通信避免一个节点解决过多的问题
另外还有读写分离,使用多个节点,主写从读;使用缓存。
3.怎么设计redis缓存
首先是考虑redis读写策略,读命中就直接返回,否则先从数据库读再更新缓存;写策略就直接写数据库,然后使得缓存数据失效,可以使用延迟双删策略。
然后是淘汰策略,可以使用近似的LRU算法,每次淘汰的时候随机采样然后淘汰最久远的。
最后是要考虑异常处理,要处理缓存穿透、击穿和雪崩的问题,可以使用记录零值、布隆过滤器解决缓存穿透问题,缓存击穿是热点数据失效导致大量请求到达数据库,可以使用互斥锁的方式去访问、热点key不失效;缓存雪崩是大量key同时过期,可以使用多级缓存或者对于过期时间增加随机过期时间。
4.怎么排查慢sql语句
首先开启慢查询日志定位慢查询的sql语句,然后使用EXPLAIN查看执行计划,判断是否使用了索引、扫描的行数,如果没有合适的索引就建立合适的索引,如果有索引要检查是否发生了索引失效的情况,比如是否函数、列计算、最左前缀匹配失效、隐式的类型转换,如果出现了这些情况就首先去修改sql语句利用索引。
如果能使用覆盖索引避免回表就利用;然后如果是select*就改成具体的列,select具体的列名。在修改完成之后就使用压测,然后重新查看执行计划检查。
总结:排查问题的思路主要是定位问题,考察多个问题然后修改;设计分布式系统主要是考虑使用中间件,使用拆分任务的思路,比如海量数据处理。
分布式限流主要是因为个人项目才会问到,排查慢sql、高并发系统是比较通用的问题。
消息队列这些还有比如手撕一个消息队列这种拓展问题,主要就是要在保证有效实现的情况下不要锁太久。