redis简介:开源的、基于内存的、可持久化的、高性能的key-value数据存储系统
redis特点:
1、高性能--内存存储,仅在需要时持久化到磁盘
2、数据类型丰富--string list hash set sortset
3、支持事务处理
4、支持批量操作--pipeline
5、支持设置key的过期时间
6、支持主从复制、故障迁移
7、支持大规模集群部署
8、支持pub\sub通讯机制
redis 功能:
高速缓存、持久化存储、消息中间件
第一部分:redis下载、安装、常用命令 redis Desktop Manager 桌面管理工具,可视化界面
lunix版本:https://redis.io/
windows版本:https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100
一般下载zip版本,便于灵活自主配置
目录结构:
redis.window.conf---redis配置文件
redis-server.exe ---安装、启动redis服务端实例
redis-cli.exe ---redis客户端程序连接、操作redis实例
dump.rdb ---数据存储文件(RDB)
操作:cmd进入redis解压缩文件目录
redis-server.exe --service -install 安装
redis-server.exe --service -uninstall 卸载
redis-cli.exe -h localhost -p 6379
keys * --查询所有key
redis-server.exe --service -install --service -name redis01 --port 6380 --requirePass 12345 -----命名、端口、密码 安装
redis-cli.exe -h localhost -p 6380 -a 12345 ----登录
auth 12345 -----密码输错时可以重新输入
key常用命令:
key set ${key} ${value} -----设置键值对
get ${key} -----取值
exists ${key} ----是否存在 存在返回1 不存在返回0
rename ${key} ${newkey} -----重命名
type ${key} ----数据类型
expire|persist|ttl ---设置过期时间、不设过期时间、查看剩余存活时间
move|migrate -----迁移到另一个实例上
server命令:
select 10 ------切换到第10个数据库,一个实例上默认16个库
dbsize -----当前数据库数据量
flushdb |flushall -----清空数据库 | 清空所有数据库
save | bgsave ------主进程保存 |子进程保存,后台保存,不阻塞
config get ---------config get requirePass
config set ---------config set requirePass 12345
config rewrite -------配置信息持久化,重写配置文件
shutdown ----断开连接
第二部分:jedisAPI ---在java中使用redis
下载\导入 jedis.jar
创建Jedis对象,连接客户端:
Jedis jedis=new Jedis("localhost",6380);
jedis.anth("12345");
1、hash 类型数据
HashMap hp=new HashMap();
hp.put("name","惠普");
hp.put("price","5000");
jedis.hmset("computer",hp); ----存入hash类型数据
jedis.hlen("computer"); ---获取元素个数
jedis.hset("computer","madein","china"); ---向hash类型的数据中增加元素
jedis.hget("computer","price"); ---获取某一个元素的value
Map<String,String> all=jedis.hgetAll("computer") ---得到一个hash类型数据的所有元素
for(String k:all.keySet()){
System.out.println(k+":"+all.get(k));
}
Set<String> keys=jedis.hkeys("computer") ; ----得到一个hash类型数据的所有key的集合
for(String k:keys){
System.out.println(k);
}
List<String> vals=jedis.hval("computer");
for(String v:values){
System.out.println(v);
}
2、list 类型数据
jedis.lpush("list-1","aa","bb","cc") --------cc bb aa 左添加
jedis.rpush("list-1","ee","ff","gg") -------cc bb aa ee ff gg
jedis.llen("list-1") ; ---查询一个列表类型的数据有几个元素
jedis.lindex("list-1",2) ; ----查询列表某个位置上的元素
jedis.lrange("list-1",0,-1) ----取得全部或部分元素
3、set 类型数据
jedis.sadd("set1","tom","jim","peter"); ---添加元素
jedis.scard("set1") ----查询集合元素个数
jedis.srem("jim") ---移除元素
Set<String> mm=jedis.smembers("set1") //获取集合数据的成员
for(String m:mm){
System.out.println(m);
}
jedis.sadd("set2","simth","rose","tom");
Set<Stirng> s=jedis.sinter("set1","set2"); //取交集
jedis.sinterstore("set3","set1","set2") //取交集后将结果保存到set3
4、sortset 数据类型
set 和 sortset区别
sortset类型数据,每个元素多了一个score属性,可以按照score进行排序和遍历
jedis.zadd("sset",100,"zion");
jedis.zadd("sset",80,"peter");
jedis.zadd("sset",60,"rose");
jedis.zadd("sset",10,"jim");
jedis.zscore("sset","jim"); //得到某个元素的score
jedis.zincrby("sset",5,"jim") //给某个元素增加5分
Set<String> mm=jedis.zrange("sset",60,100); //根据score进行遍历
第三部分:redis的管道技术
redis的主要瓶颈是网速,其次是内存容量和cpu
pipeline实现批量发出请求/一次获得响应,不必每个请求都阻塞响应,极大提升了吞吐量
在应用程序允许的情况下优先使用pipeline批量操作
Pipeline pl=jedis.pipeline(); //获取管道对象
for(int i=0;i<100000;i++){
pl.set("key"+i,"tps"); //插数据
}
pl.sync();//同步管道
//10万条数据不使用管道15000毫秒,使用900毫秒
第四部分:redis的事务处理
jedis.watch(key);//监视keys ,如果在事务体中抛异或者被监视的key被本事务以外的对象修改时,事务不会提交,事务返回值为空
Transcation tx=jedis.muti();//开始处理事务
事务体 do somthing
List<Object> r=tx.exec();//提交事务
r.isEmpt()? //判断事务是否成功,成功返回值不为空
jedis.unwatch();//解除监视
代码案例:模拟信用卡消费
jedis.set("credit","4000");//信用余额
jedis.set("debt","1000"); //债务余额
int count=1000;//消费金额
int credit=Integer.parseInt(jedis.get("credit"));
if(credit<out){
System.out.println("信用余额不足");
}else{
jedis.watch("credit","debt"); //监视数据
jedis.set("credit",8000);//模拟被监视对象被本事务以外的对象修改
Transcation t=jedis.muti();//开始处理事务
t.decrBy("credit",out);
t,incrBy("debt",out);
List<Object> r=t.exec();//提交事务
jedis.unwatch();//解除监视
if(!r.isEmpt()){
System.out.println("刷卡成功");
}else{
System.out.println("刷卡失败");
}
}
第五部分:redis的通信机制
客户端命令:subscrible ${channel}
publish ${channel} ${msg}
java 代码实现:
jedis.publish("cctv","message1");//消息发布 频道 消息内容
jedis.subscribe(JedisPubSub子类--自己写静态内部类重写onMessage(channel,message)方法;"cctv");
第六部分:redis主从库和集群部署
redis 主从库配置有两种方法:
方法一:配置文件 redis.window.conf 文件
slaveof <maste ip> <master port> ----maste ip 不能直接写localhost,要写成127.0.0.1
masterauth <master-password>
slave-read-only yes
方法二:slaveof 命令
slaveof host port //将当前库设置为从库
slaveof no one //取消从库身份
安装从数据库:
复制redis解压文件重命名
redis-server.exe --service -install redis.windows.conf --service -name redis02 --port 6381
info replication //查看主从节点信息
config set masterauth 12345 //主从节点密码一致
实现了主从复制,如果主机点宕机,如何自动切换主从节点而不影响程序运行?
哨兵机制:
复制redis解压缩文件,新增一个sentinel.conf文件,添加配置信息
port 26386
protected-mode no
dir "d:\\redis-sentinel" //哨兵目录
sentinel monitor redis01 127.0.0.1 6380 1---->当几个哨兵发现主节点宕机时可以进行转移,防止哨兵独断出问题,如果部署了3个哨兵,可以设置为2
sentinel auth-pass redis01 12345 //主从相同
sentinel down-after-milliseconds redis01 5000 //5秒联系不上判定宕机
sentinel failover-timeout redis01 15000 //15秒内完成切换
启动哨兵:
redis-server.exe sentinel.conf --sentinel
多个哨兵只需要复制sentinel.conf文件,重命名并更改port信息,启动哨兵即可,无需复制redis解压缩文件。
创建哨兵池案例:
Set<String> ips=new HashSet();
ips.add("127.0.0.1:26386");
ips.add("127.0.0.1:26387");
ips.add("127.0.0.1:26388");
创建哨兵池
JedisSentinelPool spool=new JedisSentinelPool("redis01",ips);
Jedis jedis=spool.getResource();//从哨兵池得到数据库连接对象
jedis.auth("12345");
jedis.flushAll();
for(int i=0;i<100000;i++){
jedis.set("key"+i,"tps"); //插数据
}
jedis.close();
spool.destory();//释放资源