Redis
运行速度快,并发强,运行在内存的NoSql(not only sql) 数据库
使用场景
- 缓存
- 排行榜
- 计算器/限速器,统计用户点赞,访问量,限制访问API频率
- 好友关系,共同好友,共同爱好
- 消息队列,到货通知
- session共享,不同机器之间共享session
分布式数据库CAP
- Consistency,强一致性
- Availability,高可用性,服务一直可用
- Partition tolerance,分区容错性
p是必须的,C 和 A 不能兼顾
操作命令
# 查询所有键
keys *
# 包含 k
keys *k*
# 判断 键 k1是否存在
exists k1
# 查看键k1 还有多久过期
ttl k1
# 设置过期时间 10s
expires k1 10
数据类型
string
# 值自增 +1
incr k1 1
# 自减
decr k1 1
# 自增 +3
incrby k1 3
# 对值 切片,包含全部的值
getrange k1 0 -1
# 替换 值 位置1所在的字符 aaa
setrange k1 1 aaa
# 设置k1,生命周期5s
set k1 5 v1
# m代表more,批量设置
mset k1 v1 k2 v2
# 先取值再设置值
getset k6 v6
列表List
上对应左,下对应右,比作弹夹压子弹
# lpush 栈,从上向下压入子弹
lpush list1 1 2 3
# rpush 队列
rpush list1 1 2 3
#查询list
lrange list 0 -1
#移除 2个 3
lrem list 2 3
# list[0]="x"
lsett list 0 x
# 左边插入,list中1元素前插入 java
linsert list before 1 java
Set
# 添加元素 并去重
sadd set 1 2 3
#查看元素
smembers set
# 元素个数
scard set
# 交集
sinner set1 set2
#并集并去重
sunion set1 set2
#差集,结果是set1中存在,set2不存在
sdiff set1 set2
Hash哈希
key -value结构,value存储的是key-value结构
# 添加user,id=1001
hset user id 1001
#查询user 指定字段
hget user id
#删除user id属性
hdel user id
# 获取user所有信息
hgetall user
# 获取student所有属性名
hkeys student
# 获取student所有属性值
hvals student
有序集合ZSet
# 赋值,vip1 分数(权重)10
zset zset1 10 vip1 20 vip2
# 分数 区间【20,40】
zrangebyscore zset1 20 40
# 分数 区间 (20,40】
zrangebyscore zset1 (20 40
# 取vip3下标
zrank zset1 vip3
#获取vip2分数
zscore zset1 vip2
# 大值在前 【30,20】区间
zrevrangebyscore zset1 30 20
持久化 RDB
- shutdown命令,redis自动备份,dump.rdb文件更新
- 手动备份
save
AOF(Append only File)
appendonly.aof文件 记录redis写指令操作,开机会读取操作文件,恢复数据
appendonly.aof 优先级高于 dump.rdb
事务
#开启事务
multi
set k1 v1
# 执行
exec
multi
set k1 v1
# 放弃操作
discard
发布订阅
# 订阅频道
subscribe cctv1
# 频道发布消息
publish cctv1 news
主从复制
- 读写分离,主机写,从机读
- 配从库不配主库,从机选择主机,主机无法选择从机
- 从机离线再上线,重启归来的从机成为master,离开原来的集群
# 脱离组织,自立为王
slaveof no one
复制原理
主从刚连接,进行全量同步;全同步结束后,进行增量同步
Jedis
// 连接redis
Jedis jedis= new Jedis("192.168.204.111",6379);
jedis.set("k1","v1");
// k2 是否存在
Bool exist = jedis.exists("k1");
# 获取 键k1的值
jedis.get("k1");
// 开启事务
Transaction tx = jedis.multi();
...
tx.exec();
分布式锁Redisson
zookeeper高可靠性,redis高性能。应用最多的是redis
// 通过redisson获取锁
RLock rLock = redisson.getLock(productKey);
// 上锁(过期时间为30秒)
rLock.lock(30, TimeUnit.SECONDS);
try {
...
} catch() {
} finally {
rLock.unlcok();
}
@Bean
public Redisson redisson(){
Config config = new Config(); // 使用单个redis服务器
config.useSingleServer().setAddress("redis://192.168.204.141:6379").setDatabase (0);
return (Redisson)Redisson.create(config);
}
分布式文件系统 FastDFS
- Hadoop 分布式文件系统 HDFS,大文件
- GFS
- FastDFS,适合图片,小视频小文件,对文件是不分割的,没有文件合并和切割开销
工作原理
包含Tracker Storage Server,Tracker
- Tracker
负责调用,管理存储服务 - Storage
文件存储,集群采用分组,同组内的服务器数据同步,定时向tracker汇报状态信息
RabbitMQ
消息队列 MQ
- 消息队列中间件,解决异步处理,应用解耦,流量削峰
- 消息队列是典型的生产者消费者模型
背景知识
AMQP 高级消息队列协议
JMS ,java消息服务应用程序接口,java平台面向消息中间件的API,类似JDBC角色
JMS统一消息操作,AMQP统一数据交互格式
快速入门
5672:RabbitMQ提供给编程语言客户端连接的端口
15672:RabbitMQ管理界面的端口
25672:RabbitMQ集群的端口
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
//1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//2.在工厂对象中设置MQ的连接信息(ip,port,vhost,username,password)
factory.setHost("192.168.204.141");
factory.setPort(5672); factory.setVirtualHost("/lagou"); factory.setUsername("laosun"); factory.setPassword("123123");
//3.通过工厂获得与MQ的连接
Connection connection = factory.newConnection();
RabbitMQ模式
-
点对点模式
-
发布订阅模式
消息确认机制 ACK
自动消息确认
// 4.监听队列 true:自动消息确认
channel.basicConsume("queue1", true,consumer);
手动消息确认
// 手动确认(收件人信息,是否同时确认多个消息)
channel.basicAck(envelope.getDeliveryTag(),false);
// 4.监听队列,false:手动消息确认
channel.basicConsume("queue1", false,consumer);
工作队列模型
能者多劳类型,开启手动确认消息
// 声明队列(此处为消费者,不是声明创建队列,而且获取,二者代码相同)出餐口排队 。已经存在就获取,不存在就创建
channel.queueDeclare("test_work_queue",false,false,false,null);
// 可以理解为:快递一个一个送,送完一个再送下一个,速度快的送件就多
channel.basicQos(1);
避免消费堆积
-
workqueue,多个消费者监听同一个队列
-
接收到消息后,通过线程池,异步消费
发布订阅模型
生成者发送消息给路由,路由转发给队列
// 路由声明,参数 路由名,路由类型
channel.exchangeDeclare("test_exechange_fanout","fanout");
路由模式
路由根据类型定向分发消息给队列
- 先运行生产者,创建路由器
- 再创建Receiver,进行队列绑定
- 再次运行sender,发出消息
/Sender.java/
// 生产者
channel.exchangeDeclare("test_exechange_direct","direct");
// insert路由键
channel.basicPublish("test_exchange_direct", "insert", null, msg.getBytes());
/Receiver.java/
// 声明队列
channel.queueDeclare("test_exchange_direct_queue_1",false,false,false,null);
// 绑定路由(如果路由键的类型是 添加,删除,修改 的话,绑定到这个队列1上)
channel.queueBind("test_exchange_direct_queue_1", "test_exchange_direct", "insert");
通配符模式 topic
*:只能匹配一个单词
#:匹配0个或多个单词
事务机制
通过信道开启事务
-
channel.txSelect()
开启事务 -
channel.txCommit()
提交事务 -
channel.txRolleback()
回滚事务
confirm模式
消息发送失败,采用补发消息完成消息的送达
过期时间TTL
队列设置,队列中所有消息有相同的过期时间
<!--2.重新配置一个队列,同时,对队列中的消息设置过期时间-->
<rabbit:queue name="test_spring_queue_ttl" auto-declare="true">
<rabbit:queue-arguments>
<entry key="x-message-ttl" value-type="long" value="5000"></entry>
</rabbit:queue-arguments>
</rabbit:queue>
对消息设置,每条消息的TTL可以不同(单位毫秒)
同时设置 队列和消息,时间小的起作用
死信队列
消息没有及时消费,消息在队列中变成死信,消息就会绑定到死信交换机,绑定死信交换机的是死信队列
集群
搭建集群,之前创建的交换机,队列,用户属于单一结构,在新的集群环境不可用
集群镜像模式
将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态一致
set_policy {name} {pattern} {definition}
- name:策略名
- pattern:队列的匹配模式,"^queue_" 表示对队列名称以“queue_”开头的所有 队列进行镜像,而"^"表示匹配所有的队列
- definition:镜像定义,ha-mode高可用模式,有效值为 all/exactly/nodes,当前策略模式为 all,即复制到所有节点,包含新增节点
rabbitmqctl set_policy xall "^" '{"ha-mode":"all"}'
HAProxy
HAProxy是一款提供高可用性,负载均衡,并且基于TCP和HTTP应用的代理软件
KeepAlived
keepalived基于vrrp(Virtual Router Redundancy Protocol,虚拟路由冗余协议)协议,vrrp它 是一种主备(主机和备用机)模式的协议,通过VRRP可以在网络发生故障时透明的进行设备切换 而不影响主机之间的数据通信
网友评论