很多的数据类型用户的个人信息, 社交网络,地理位置。这些数据类型的存储不需要一个固定的格式 !不需要多月的操作就可以横向扩展的! Map
NOSQL特点
方便扩展(数据之间没有关系,很好扩展!)
大数据量高性能
数据类型是多样型的
传统RDBMS和nosql
传统的RDBMS和nosql
-结构化组织
-SQL
-数据和关系都存在单独的表中
-操作,数据定义语言
-严格一致性
-基础事务
nosql
-不仅仅是数据
-没有固定的查询语句
-键值对存储,列存储,图形数据库(社交关系)
-高性能,高可用,高扩展
大数据时代的3V:主要是描述问题的
1.海量 volume
2.多样
3.实时
三高
高并发
高扩展
高性能
先安装 gcc-c++
yum install gcc-c++
make
make install
报错:
1 make[1]: *** [server.o] Error 1
原因是因为gcc版本过低,yum安装的gcc是4.8.5的。因此需要升级gcc,升级过程如下:
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
#这句是临时的
scl enable devtoolset-9 bash
#修改环境变量
echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile
gcc -v
redis的默认安装路径/usr
[root@master redis-6.0.5]# cd /usr/
[root@master usr]# ls
bin games lib libexec sbin src
etc include lib64 local share tmp
[root@master usr]# cd local/
[root@master local]# ls
bin etc games include lib lib64 libexec sbin share src
[root@master local]# cd bin/
[root@master bin]# ls
redis-benchmark redis-check-rdb redis-sentinel
redis-check-aof redis-cli redis-server
[root@master bin]# pwd
/usr/local/bin
测试
#测试:100并发 100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
基础知识
redis默认有十六个数据库
默认使用的是第0个
可以使用select进行切换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MGhcHnmO-1596033904628)(C:\Users\diudiu\AppData\Roaming\Typora\typora-user-images\image-20200720192839962.png)]
redis是单线程 (6379 粉丝效应)
明白redis是很快的,官方表示,redis是基于内存操作,CPU不是redis性能瓶颈,redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程来实现,就使用单线程了!所以就使用了单线程
redis是C语言写的,官方提供的数据为100000的QPS,完全不比同样是使用key-value的memecache差!
redis为啥单线程还这么快
1误区1:高性能的服务器一定是多线程?
2误区2:多线程(cpu上下文切换)一定比单线程效率高
核心:redis是将所有的数据全部放在内存中的,所有说使用单线程去操作效率就是最高的,多线程(cpu上下文切换:耗时操作),对于内存系统来说,如果没有上下切换效率就是最高的!多次读写都在一个CPU上,在内存情况下这个就是最佳方案
Redis是一个开源( BSD许可)的,内存中的数据结构存储系统,它可以用作 数据库 、缓存和消息中间件MQ。它支持多种类型的数据结构,如字符串( strings),散列(hashes) ,列表(lists),集合(sets) ,有序集合( sortedsets)与范围查询,bitmaps,hyperloglogs 和地理空间( geospatial )索引半径查询。Redis 内置了复制( replication) , LUA脚本(Luascripting) , LRU驱动事件( LRU eviction) , 事务( transactions )和不同级别的磁盘持久化( persistence ) , 并通过Redis哨兵( Sentinel )和自动分区( Cluster )提供高可用性( high availability )。
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> EXISTS age
(integer) 1
127.0.0.1:6379> EXISTS age1
(integer) 0
127.0.0.1:6379> MOVE age
(error) ERR wrong number of arguments for 'move' command
127.0.0.1:6379> MOVE age 1
(integer) 1
127.0.0.1:6379> set name qwc
OK
127.0.0.1:6379> get name
"qwc"
127.0.0.1:6379> EXPIRE name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 5
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 2
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)
##################################################################
127.0.0.1:6379> set key1 v1 #设置值
OK
127.0.0.1:6379> get key1 #获取值
"v1"
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> EXISTS key1 #是否存在
(integer) 1
127.0.0.1:6379> APPEND key1 hello #追加
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> STRLEN key1 #获取长度
(integer) 7
127.0.0.1:6379> APPEND key1 ,qwc
(integer) 11
127.0.0.1:6379> get key1
"v1hello,qwc"
##################################################################
#i++
#步长
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> DECR views
(integer) 1
127.0.0.1:6379> DECR views
(integer) 0
127.0.0.1:6379> DECR views
(integer) -1
127.0.0.1:6379> INCR views
(integer) 0
127.0.0.1:6379> INCRBY views 10
(integer) 10
127.0.0.1:6379> INCRBY views 10
(integer) 20
127.0.0.1:6379> INCRBY views 10
(integer) 30
127.0.0.1:6379> DECRBY views 5
(integer) 25
127.0.0.1:6379> DECRBY views 5
(integer) 20
127.0.0.1:63
##################################################################
#字符串范围range
127.0.0.1:6379> set key1 hello,kuagns
OK
127.0.0.1:6379> GETRANGE key1 0 4
"hello"
127.0.0.1:6379> GETRANGE key1 0 -1
"hello,kuagns"
#替换
127.0.0.1:6379> set key2 abcdef
OK
127.0.0.1:6379> SETRANGE key2 1 xx
(integer) 6
127.0.0.1:6379> get key2
"axxdef"
127.0.0.1:6379>
##################################################################
#setex(set with exoire) #设置过期时间
#setnx(set if not exist) #不存在在设置(在分布式锁中会常常使用! )
127.0.0.1:6379> setex key3 20 hello #设置key3 hello 20秒过期
OK
127.0.0.1:6379> ttl key3
(integer) 15
127.0.0.1:6379> SETNX mykey redis #不存在就设置
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
2) "key2"
3) "key1"
127.0.0.1:6379> SETNX mykey mogondb #存在就不能设置
(integer) 0
127.0.0.1:6379> get mykey
"redis"
127.0.0.1:6379>
##################################################################
#mset
#mget
127.0.0.1:6379> mset key1 v1 k2 v2 k3 v3 #同时设置多个值
OK
127.0.0.1:6379> mget key1 k2 k3 #同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k2 v2 k4 v4 #msetnx是一个原子性操作,要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379>
#对象
set user:1 {name:zhangshan,age:3}
127.0.0.1:6379> mset user:1:name zhangshan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangshan"
2) "2"
##################################################################
getset #先get再set
127.0.0.1:6379> getset db redis #如果不存在值,则返回ni1
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb #如果存在值,获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"
数据结构是想通的
string类型的使用场景:value 除了是我们的字符串还可以是数字
127.0.0.1:6379> LPUSH list1 one
(integer) 1
127.0.0.1:6379> LPUSH list1 two
(integer) 2
127.0.0.1:6379> LPUSH list1 three
(integer) 3
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list1 0 1
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list1 right
(integer) 4
127.0.0.1:6379> LRANGE list1 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
小结
●他实际上是一个链表, before Node after ,left , right都可以插入值
●如果key不存在,创建新的链表
●如果key存在,新增内容
●如果移除了所有值,空链表,也代表不存在!
●在两边插入或者改动值,效率最高!中间元素,相对来说效率会低一点
消息队列(lpush rpop),栈(lpush lpop)
set中的值不能重复,无序
############################################################################
127.0.0.1:6379> SADD myset hello #set集合中添加元素
(integer) 1
127.0.0.1:6379> SADD myset qwc
(integer) 1
127.0.0.1:6379> SADD myset qwc
(integer) 0
127.0.0.1:6379> SADD myset qwc1
(integer) 1
127.0.0.1:6379> SADD myset qwc2
(integer) 1
127.0.0.1:6379> SMEMBERS myset #查看set的所有值
1) "qwc2"
2) "hello"
3) "qwc"
4) "qwc1"
127.0.0.1:6379> SISMEMBER myset hello #判断某一个值是不是在set集合中
(integer) 1
127.0.0.1:6379> SISMEMBER myset q
(integer) 0
############################################################################
7.0.0.1:6379> SCARD myset #获取set 集合中的元素个数
(integer) 4
127.0.0.1:6379> SREM myset qwc #移除某一个元素
(integer) 1
127.0.0.1:6379> SCARD myset
(integer) 3
127.0.0.1:6379> SMEMBERS myset
1) "qwc2"
2) "hello"
3) "qwc1"
############################################################################
set 无序不重复集合
127.0.0.1:6379> SRANDMEMBER myset #随机抽选出一个元素
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"qwc2"
127.0.0.1:6379> SRANDMEMBER myset
"qwc1"
127.0.0.1:6379> SRANDMEMBER myset
"qwc2"
127.0.0.1:6379> SRANDMEMBER myset
"qwc2"
127.0.0.1:6379> SRANDMEMBER myset 2 #随机抽选出指定个数的元素
1) "hello"
2) "qwc2"
127.0.0.1:6379> SRANDMEMBER myset 2
1) "hello"
2) "qwc1"
127.0.0.1:6379> SRANDMEMBER myset 2
1) "qwc2"
2) "qwc1"
############################################################################
删除指定的key,删除随机key
127.0.0.1:6379> SMEMBERS myset
1) "qwc2"
2) "hello"
3) "qwc1"
127.0.0.1:6379> spop myset
"qwc1"
127.0.0.1:6379> SMEMBERS myset
1) "qwc2"
2) "hello"
127.0.0.1:6379> SMOVE myset qwc myset2
(integer) 0
127.0.0.1:6379> SMOVE myset myset2 qwc
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "world"
127.0.0.1:6379> SMEMBERS myset2
1) "qwc"
2) "set2"
############################################################################
微博,B站,共同关注! (并集)
数字集合类:
-差集 SDIFF
-交集 SINTER
-并集 SUNION
127.0.0.1:6379> SADD key1 a
(integer) 1
127.0.0.1:6379> SADD key1 b
(integer) 1
127.0.0.1:6379> SADD key1 c
(integer) 1
127.0.0.1:6379> SADD key1 d
(integer) 1
127.0.0.1:6379> SADD key2 c
(integer) 1
127.0.0.1:6379> SADD key2 d
(integer) 1
127.0.0.1:6379> SADD key2 e
(integer) 1
127.0.0.1:6379> SDIFF key1 key2
1) "b"
2) "a"
127.0.0.1:6379> SINTER key1 key2
1) "d"
2) "c"
127.0.0.1:6379> SUNION key1 key2
1) "c"
2) "a"
3) "b"
4) "d"
5) "e"
微博,A用户将所有关注的人放在set集合中!将他的粉丝也放在一个集合中
共同关注,共同爱好,二度好友,推荐好友
Map集合,key-
set myhash field1 qwc
127.0.0.1:6379> HSET myhash field1 qinweichao #set一个具体的key-value
(integer) 1
127.0.0.1:6379> HGET myhash field1
"qinweichao"
127.0.0.1:6379> HMSET myhash field1 hello field2 word #set多个的key-value
OK
127.0.0.1:6379> HMGET myhash field1 field2 #获取多个字段值
1) "hello"
2) "word"
127.0.0.1:6379> HGETALL myhash #获取全部值
1) "field1"
2) "hello"
3) "field2"
4) "word"
127.0.0.1:6379> HDEL myhash field1 #删除指定key 对应的value也消失了
(integer) 1
127.0.0.1:6379> HGETALL myhash
1) "field2"
2) "word"
127.0.0.1:6379> HLEN myhash #获取长度
(integer) 1
127.0.0.1:6379>
####################################################################
#只获得所有field
#只获得所有value
127.0.0.1:6379> keys *
1) "myhash"
127.0.0.1:6379> hkeys myhash
1) "field2"
127.0.0.1:6379> HVALS myhash
1) "word"
####################################################################
inc decr
127.0.0.1:6379> hset myhash field3 5
(integer) 1
127.0.0.1:6379> HINCRBY myhash field3 1
(integer) 6
127.0.0.1:6379> HINCRBY myhash field3 -1
(integer) 5
127.0.0.1:6379> HSETNX myhash field4 hello #不存在可以设置
(integer) 1
127.0.0.1:6379> HSETNX myhash field4 world #存在不能设置
(integer) 0
hash变更的数据 user name age,尤其是用户信息之类的,经常变动的信息!hash更适合于对象的存储,string更适合字符串的存储!
在set的基础上,增加了一个值,set k1 v1 zset
127.0.0.1:6379> ZADD myset 1 one #添加一个值
(integer) 1
127.0.0.1:6379> ZADD myset 2 two 3 three #添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379>
127.0.0.1:6379> ZADD salary 2500 a
(integer) 1
127.0.0.1:6379> ZADD salary 3000 b
(integer) 1
127.0.0.1:6379> ZADD salary 3500 c
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> ZRANGEBYSCORE salary +inf -inf
(empty array)
127.0.0.1:6379> ZRANGEBYSCORE salary 0 -1
(empty array)
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores #升序排序
1) "a"
2) "2500"
3) "b"
4) "3000"
5) "c"
6) "3500"
127.0.0.1:6379> ZREVRANGEBYSCORE salary +inf -inf withscores #降序排序
1) "c"
2) "3500"
3) "b"
4) "3000"
5) "a"
6) "2500"
#############################################################
移除rem
127.0.0.1:6379> zrem salary a
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "b"
2) "c"
127.0.0.1:6379> ZCARD salary #获取个数
(integer) 2
127.0.0.1:6379> ZCOUNT salary 0 2000 #计数
(integer) 0
127.0.0.1:6379> ZCOUNT salary 0 3000
(integer) 1
127.0.0.1:6379> ZCOUNT salary 0 4000
(integer) 2
其余的一些API ,通过我们的学习吗,你们剩下的如果工作中有需要,这个时候你可以去查查看官方文档!
案例思路: set排序存储班级成绩表,工资表排序!
普通消息,1,重要消息2 ,带权重进行判断!
排行榜应用实现
朋友的定位,附近的人,打车距离计算?
Redis的Geo在Redis3.2版本就推出了!
可以查询一些测试数据: http://www.jsons.cn/lngcodeinfo/0706D99C19A781A3/
geoadd
#geoadd 添加地理位置
#规则:两极无法自接添加,我们一般会下载城市数据,直接通过java程序一次性导入
#有效的经度从-180度到180度。
#有效的纬度从-85. 05112878度到85.05112878度。
#当坐标位置超出上述指定范围时,该命令将会返回一个错误。
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 114.05 22.52 shengzhen 120.16 30.24 hangzhou
(integer) 2
getpos
127.0.0.1:6379> GEOPOS china:city beijin
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city beijin shengzhen
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
2) 1) "114.04999762773513794"
2) "22.5200000879503861"
127.0.0.1:6379>
geodist
两人之间的距离!
单位:
●m表示单位为米。
●km表示单位为干米。
●mi表示单位为英里。
●ft表示单位为英尺。
127.0.0.1:6379> geodist china:city beijin shanghai km
"1067.3788"
georadius
我附近的人? ( 获得所有附近的人的地址,定位! )通过半径来查询!
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km
1) "chongqing"
2) "shengzhen"
3) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km
1) "chongqing"
geohash
该命令将返回1 1个字符的Geohash字符串!
#将二维的经纬度转换为- -维的字符串,如果两个字符串越接近,那么则距离越近!
127.0.0.1:6379> GEOHASH china:city beijin chongqing
1) "wx4fbxxfke0"
2) "wm5xzrybty0"
GEO底层的实现原理其实就是zset
127.0.0.1:6379> ZRANGE china:city 0 -1 #查看地图全部元素
1) "chongqing"
2) "shengzhen"
3) "hangzhou"
4) "shanghai"
5) "beijin"
127.0.0.1:6379> zrem china:city beijin #删除地图指定元素
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chongqing"
2) "shengzhen"
3) "hangzhou"
4) "shanghai"
什么是基数?
A{1,3,5,7,8,7}
B{1 ,3,5,7,8}
基数(不重复的元素) =5
简介
Redis 2.8.9版本就更新了Hyperloglog数据结构!
Redis Hyperloglog 基数统计的算法
优点:占用的内存是固定,2^64不同的元素的技术,只要12KB内存!如果要从内存角度来比较的话Hyperloglog首选!
网页的UV((一个人访问一个网站多次,但是还是算作一个人!)
传统方式,set保存用户的id,然后就可以统计set中的元素数量作为标准判断
这个方式如果保存大量的用户id,就会比较麻烦!我们的目的是为了计数,而不是保存用户id;
0.81%错误率!统计UV任务,可以忽略不计的!
测试使用
127.0.0.1:6379> PFadd mykey a b C defghij # 创建第一组元素mykey
(integer) 1
127.0.0.1:6379> PFCOUNT mykey # 统计mykey元素的基数数量
(integer) 10
127.0.0.1:6379> PFadd mykey2 i j z x cvbnm #创建第二组元素mykey2
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 ##合并两组mykey mykey2 => mykey3并集
127.0.0.1:6379> PFCOUNT mykey3 #查看并集数
(integer) 15
如果允许容错,那么一定可以使用Hyperloglog
如果不允许容错,就使用set或者自己的数据类型即可
位存储
统计疫情感染人数:01010
统计用户信息,活跃,不活跃! 登录、未登录!打卡,365打卡!两个状态的都可以使用Bitamaps位图,数据结构! 都是操作二进制位来进行记录,就只有0和1
使用bitmap来记录周一到周日的打卡!
周一:1 ;周二:0
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vgAPSESX-1596033904639)(C:\Users\diudiu\AppData\Roaming\Typora\typora-user-images\image-20200721111442411.png)]
查看某一天是否打卡
127.0.0.1:6379> GETBIT sign 2
(integer) 1
127.0.0.1:6379> GETBIT sign 5
(integer) 0
统计打卡天数
127.0.0.1:6379> BITCOUNT sign
(integer) 4
mysql:acid要么同时成功,要么同时失败,原子性!
redis单条保持原子性的,但是事务不保证原子性
redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
一次性、顺序性、排他性、
-----队列 set set set 执行----
redis 事务没有隔离级别的概念
所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行! Exec
Redis单条命令式保存原子性的,但是事务不保证原子性!
redis的事务:
●开启事务( multi)
●命令入队( …)
●执行事务( exec)
正常执行事务!
127.0.0.1:6379> MULTI #开启事务
OK
#命令入队
127.0.0.1:6379> set k1 v2
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec #执行事务
1) OK
2) OK
3) "v2"
4) OK
放弃事务
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> get k4
(nil)
编译型异常(代码有问题!命令错误),事务中的命令都不会执行
127.0.0.1:6379> mu1ti
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127. 0.0.1:6379> getset k3|
(error) ERR wrong number of arguments for ' getset' command
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors .
127.0.0.1:6379> get k5
(ni1)
运行时异常( 1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,
127.0.0.1:6379> set k1 "v1"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr kl
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec
1) Cerror) ERR value is not an integer or out of range # 虽然第一条命令报错了,但是依旧正常执行成功了
2) OK
3) OK
4) "v3"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k3
"v3"
监控
悲观锁:
乐观锁:
redis监控测试
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money #监视money对象
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
测试多线程修改值,使用watch可以当作redis的乐观锁操作!
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>
如果修改失败,获取最新的值就行
我们要使用Java来操作Redis
什么是Jedis是Redis官方推荐的java连接开发工具!使用ava操作Redis中间件!如果你要使用 java操作redis,那么一定要对jedis十分熟悉
测试
1.导入对应依赖
<dependencies>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>3.3.0version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.72version>
dependency>
dependencies>