技能储备

JAVA基础

JVM

设计模式

技术栈

Redis(Remote Dictionary Server(远程数据服务))缓存

Redis是基于内存的高速缓存key-value数据库(C语言开发)

优点

1.基于内存读写速度快,可以支持高性能的业务场景

2.支持丰富的数据结构(String,hash,set,list,sort)

3.QPS可以达10万+

缺点

  1. 数据不一致
  2. 缓存雪崩
  3. 缓存穿透
  4. 缓存并发
  5. 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写

数据不一致问题(mysql+redis)

业界方案:监听mysql的binlog日志,异步淘汰缓存

缓存雪崩(大量缓存同时失效,导致直接查DB,导致DB压力太大奔溃)

业界方案:将热点数据设置不同的过期时间,以防止同时查询热点数据给数据库带来压力

缓存穿透(针对用户恶意攻击)

在查询缓存没有值,再查询mysql也没有值时,会将此key的value设置为null,并添加六十秒过期时间

业界方案:布隆过滤器(存在误算率,随着存入的元素数量增加,误算率也随着增加)

布隆过滤器的思想:核心是实现了一个超大的位数组和几个哈希函数,每一个元素,都调用这几个哈希函数算出哈希值,并落到这个数组中,随着元素的增加,哈希值的相似度就会升高,误判率就会出现

 

Redis热点key的寻找方案

redis于4.0.3版本开始正式支持基于LFU的热点key发现机制。

Least Frequently Used——简称LFU,意为最不经常使用,是redis4.0新增的一类内存逐出策略,从LFU的字面意思我们很容易联想到key的访问频率,并对访问频率进行了统计

可以对概率因子和衰减因子进行配置,推荐使用redis的默认值即可:

lfu-log-factor 10lfu-decay-time 1要注意需要先把内存逐出策略设置为allkeys-lfu或者volatile-lfu,否则会返回错误

redis 4.0.3同时也提供了redis-cli的热点key发现功能,执行redis-cli时加上–hotkeys选项即可,示例如下:$./redis-cli –hotkeys 排在前面就是热点key

Redis和Memcache对比

 

Redis

Memcache

数据结构

多种数据结构:String,hash,set,list,sort

Key-value

集群模式

Redis自带(redis cluster)

客户端自己实现

线程模式

单线程(小数据量性能好,可以持久化)

多线程(大数据量100M性能好,不能持久化)

 


 

 

 

 

 

 

 

 

 

 

MQ(Message Queue)消息队列

MQ:是一种应用程序对应用程序传递消息的中间件,是通过读写出入队列来通信。

三种通讯模式 1.点对点,2.多点广播,3.发布和订阅(一般用这个)

优点

1.异步:执行失败重试,提高接口的性能(失效策略;数据回补)

2.解耦:利用MQ降低系统的耦合性(系统重构)

3.削峰:将一些无需及时返回且耗时的操作提取出来,进行异步处理,从而节省服务器的响应时间来提高系统的吞吐量(秒杀,公司的活动:抢金币)

缺点

1.MQ一旦挂了,整个系统就奔溃了(高可用)

2.系统的复杂度提高(消息堆积)

3.数据不一致(消息重复,消息顺序,消息丢了)

如何选型:RabbitMQ,RocketMQ,Kafka

Kafka是主要用于配合大数据类的系统来进行实时数据计算、日志采集等场景(主要支持简单的MQ功能)

我们一般在RabbitMQ和RocketMQ中间来选择

选择RocketMQ的理由(阿里出品):

1.topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降(RabbitMQ会大幅下降)

2.分布式集群,每个部分都可以水平扩展(RabbitMQ主从集群)

3.java开发(RabbitMQ用erlang语言开发)

4.吞吐量是10万级(RabbitMQ是万级)

缺点:

1.延时毫秒级(RabbitMQ是微秒级)

2.社区活跃度一般(RabbitMQ比较好版本迭代特别快)

 

MQ的高可用

RabbitMQ是镜像集群模式(主从)

Kafka是分布式集群(副本集,HA),每个节点都有一个replicate备份。读写都在leader节点

RocketMQ是分布式集群如下

Name Server:主要提供轻量级查找和路由服务(保存了其它三部分的信息)(各个节点之间不通信)

Broker Cluster:轻量的topic和queue机制(消息的存储,支持push和pull)

Product Cluster:分布式的producers通过负载均衡模型向broker发送消息

Consumer Cluster:支持push,pull,支持集群消费与消息广播同时提供实时订阅

 

 

MQ的消息幂等性(不重复)

造成的原因:1.系统重启  2.网络异常  3.消费失败

解决方案

  1. 消息的唯一标识存入redis中并进行判断
  2. 数据库的存储判断

MQ丢消息

  1. producter:发送消息状态超时或者失败,则会触发默认的2次重试(支持日志的索引查找)
  2. broker:是一主多从的节点,同时支持同步和异步刷盘的策略,保证消息落到本地内存中,消息也支持持久化到commitlog里面,即使宕机,未消费的消息也可以加载出来
  3. consumer:确保拉取到的消息成功消费,consumer自身维护了一个持久化的offset,消费成功后才会更新自己的offset,offset会持久化到本地,即使consumer挂掉重启之后可以继续拉取offset之前的消息到本地

MQ消息的积压

策略:超出了buffer,也可以丢弃,然后再从CommitLog中补数据

打开rocketmq的控制台查看是历史消费记录,如果是消息写入速度大于消息的消费速度,调整业务代码或对消费者进行扩容

Consumer消费消息出现问题,只能操作临时紧急扩容了,具体操作步骤和思路如下:

1)先修复consumer的问题,确保其恢复消费速度,然后将现有cnosumer都停掉

2)新建一个topic,partition是原来的10倍,临时建立好原先10倍或者20倍的queue数量

3)然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue

4)接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据

5)这种做法相当于是临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据

6)等快速消费完积压数据之后,得恢复原先部署架构,重新用原先的consumer机器来消费消息

MQ消息的顺序

避开这种使用场景

数据库

Mysql事务默认(可重复读)

事务隔离级别

脏读

不可重复读

幻读

读未提交(read-uncommitted

不可重复读(read-committed

可重复读(repeatable-read

串行化(serializable

 脏读:一个事务读到另一个事务未提交的更新数据

幻读:已提交的插入数据

 

 

 

 

mysql默认的事务隔离级别为repeatable-read

 

网络

URL解析统一资源定位符 (Uniform Resource Locator, URL) 

调用链路

http://www.baidu.com(scheme:通信协议, host:主机, port:端口号)

 

DNS解析(DNS缓存)

 

TCP连接

 

发送http请求

 

服务器处理请求并返回http报文

 

浏览器解析渲染页面

 

连接结束

 

 

 

 

 

 

 

 

思考

秒杀设计思路

用户量不大的策略

队列+redis全局计数器即可

用户量大的策略(柔性服务策略)

  1. 前端处理95%的请求直接返回已经售光(前端随机数,矩阵,离散等概率算法)
  2. 全局计数处理
  3. 降级跳过非关键逻辑
  4. 中间错误异步修复
  5. 业务流程上可以通过:抢购预约码

 

有损服务的策略(列表页)

第一种策略

         列表页分为三块,同时发起三个异步请求后端进行处理

 

第二种策略

         A:搜索筛选项时,比如搜索海淀-知春路的帖子,只出海淀的帖子(维度高一些)

         B:第三块是广告页可以选择不展示

         C:列表页中的数据可以继续简化(简化埋点,日志,广告等业务数据)

         D:筛选项可以进行15分钟一次的缓存刷新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章