解决功能性的问题:JAVA、JSP、RDBMS、Tomcat、HTML、Linux、JDBC、SVN
解决扩展性的问题:Struts、Spring、SpringMVC、Hibernate、MyBatis
解决性能的问题:NoSQL、JAVA线程、Hadoop、Nginx、MQ、ElasticSearch
https://www.cnblogs.com/superxuezhazha/p/13643873.html
缓存数据库:减少IO操作
NoSQL: Not Only SQL,意为"不仅仅是SQL",泛指非关系型数据库。
NoSQL不依赖业务逻辑的方式进行存储,使用简单的Key-Value键值对进行存储。
ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:
原子性(atomicity,或称不可分割性)
一致性(consistency)
隔离性(isolation,又称独立性)
持久性(durability)
Redis
MongoDB
(120条消息) Redis和MongoDB的区别(面试受用)_孜孜不倦,不紧不慢的博客-CSDN博客_mongodb redis
这里我使用的是Docker的虚拟环境,在官网下载并安装Docker,然后将WSL2问题(Linux的内核)处理完成之后,在DockerHUB中搜索Redis,然后往下找到quickStart,在控制台中输入,Docker自动构建运行环境。
Redis的端口号为6379
默认有16个数据库,下标从0开始
统一密码管理,所有库相同的密码
dbsize查看当前数据库的key数量
flushdb清空当前库
flushall清空所有库
Redis使用的技术
Redis使用的是单线程+多路IO复用技术
多路复用是指一个线程来检查多个文件描述符Socket的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。
得到就绪状态后进行真正的操作,可以在同一个线程里面执行,也可以启动线程执行(比如线程池)
set [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JmozSeVC-1690358602374)(./Redis.assets/image-20220902161447719.png)]
get [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FpFUpSIO-1690358602379)(./Redis.assets/image-20220902161451927.png)]
keys *
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ByiqJLFt-1690358602383)(./Redis.assets/image-20220902161201558.png)]
exists [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3J4LRNao-1690358602388)(./Redis.assets/image-20220902161233296.png)]
type [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IYBeWQ3K-1690358602393)(./Redis.assets/image-20220902161318783.png)]
del [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n5detPed-1690358602397)(./Redis.assets/image-20220902161529192.png)]
unlink [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CDuW0YAm-1690358602402)(./Redis.assets/image-20220902161618343.png)]
empire [key] 10
单位:秒。10秒后key将会自动销毁。当过期时间为-1时,永不过期。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jk1z0iT9-1690358602406)(./Redis.assets/image-20220902161837854.png)]
时间过了之后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zyIf8kZm-1690358602411)(./Redis.assets/image-20220902161923495.png)]
get不到Key3
ttl [key]
查看key还有多少秒过期,-1表示永不过期,-2表示已经过期
未过期:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2GaagdF-1690358602415)(./Redis.assets/image-20220902161842607.png)]
已过期:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ssgTlVYA-1690358602420)(./Redis.assets/image-20220902161853806.png)]
select
切换数据库,如select 1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tXCiISEd-1690358602424)(./Redis.assets/image-20220902162050873.png)]
dbsize
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xasJq1F2-1690358602429)(./Redis.assets/image-20220902162038735.png)]
flushdb
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wcDF1NS4-1690358602433)(./Redis.assets/image-20220902162201063.png)]
flushall
String是Redis最基本的类型。一个key对应一个Value。
String类型是二进制安全的,意味着Redis的String可以包含任何数据。比如jpeg图片或者序列化的对象。
String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M
数据结构
String的数据结构为简单动态字符串(Simple Dynamic String,SDS)。
是可以修改的字符串,内部结构实现类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
当前实际分配的空间一般要高于实际字符长度,当字符串小于1M时,扩容都是加倍现有的空间,扩容时一次只会多扩1M的空间。
需要注意的是字符串最大长度为512M。
添加
set [key] [value]
设置key和value的一对一对应
除此之外,set还有其它的用法:
*nx:当数据库中key不存在时,才可以将key-value添加到数据库
*xx:当数据库中key存在时,才可以将key-value添加到数据库,与nx互斥
*ex:key的超时秒数
*px:key的超时毫秒数,与ex互斥
使用方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PuV7RKfH-1690358602438)(./Redis.assets/image-20220902163638083.png)]
在set后面加上后缀即可(上图是 *nx 的效果,即只有当数据库中的key1不存在时,才可以将key1添加到数据库,第一次成功,第二次失败)。
通过以下命令,在创建key时,同时赋值key的过期时间,单位:秒
setex age 10 22
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggQpNQsY-1690358602442)(./Redis.assets/image-20220902170116919.png)]
获取某个key所对应的值
get [key]
以新换旧
设置新值的时候同时获取旧值。
getset [key] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wQzllhYH-1690358602447)(./Redis.assets/image-20220902170309138.png)]
在key后面追加内容
append [key] [value]
在该key原有的value后面添加value,如:
key1原value为a,在执行append key1 b后,key1的value变为 ab
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jxAqxmOT-1690358602451)(./Redis.assets/image-20220902163910755.png)]
长度
strlen [key]
获取某个键的value长度
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85HGKRi0-1690358602456)(./Redis.assets/image-20220902164033078.png)]
与java、C++中的i++自增不同,Redis的自增操作具有原子性,操作一次完成,不会被其它操作打断。
原子操作指的是不会被线程调度机制打断的操作。
在单线程中,能够在单条指令中完成的操作都可以认为是[原子操作],因为终端只能发生于指令之间
在多线程中,不能被其它进程(线程)打断的操作就叫做[原子操作]。
Redis单命令的原子性主要得益于Redis是单线程操作。
自增
incr [key]
要求该key必须为数字类型,即不能有任何的其它字符出现
若该key为空,则新增值为1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kh4TuEin-1690358602460)(./Redis.assets/image-20220902164235121.png)]
自减
decr [key]
同样要求该key必须为数字类型,即不能有任何的其它字符出现
若key值为空,则新增值为-1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RMHykwMU-1690358602465)(./Redis.assets/image-20220902164246438.png)]
自增/自减
incrby / decrby [key] [步长]
将key中存储的值(需为数字)按照步长增减。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NQifyJn0-1690358602469)(./Redis.assets/image-20220902164545669.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HKdi283n-1690358602474)(./Redis.assets/image-20220902164556151.png)]
添加多个
mset [key1] [value1] [key2] [value2] ...
或者与后缀结合使用
msetnx [key1] [value1] [key2] [value2] ...
可以同时设置多个key-value的键值对
原子性,有一个失败则全都失败
获取多个key的值
mget [key1] [key2] [key3]
原子性,有一个失败则全都失败
切割字符串
getrange [key] [起始位置] [结束位置]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BdcHiszN-1690358602479)(./Redis.assets/image-20220902165804668.png)]
setrange [key] [起始位置] [value]
赋值字符串
用value覆盖key所在的字符串值,从[起始位置]开始。【默认索引从0开始】
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1GhsR2z3-1690358602483)(./Redis.assets/image-20220902165918009.png)]
单键多值
Redis列表是简单的字符串列表,按照插入顺序排序。
可以添加元素到列表的左边或者右边(头部或者尾部)
底层实现是双向链表,对两端的操作性能很高,但是通过索引访问中间性能较差(链表的特效:查询效率低,插入效率高)
数据结构
List的数据结构为快速链表quickList
首先在列表元素较少的情况下会使用一块连续的内存进行存储,这个结构是zipList,也就是压缩列表。
它将所有的元素紧挨着一起存储,分配的是一块连续的内存。
当数据量较多时,会改为quickList。
因为普通的链表需要的附加指针空间太大,会比较浪费空间。
Redis将链表和ZipList结合起来组成了quickList。也就是将多个ZipList使用双向指针串起来使用。
这样既满足快速插入删除的性能,又不会出现太大的空间冗余
lpush:left push 往列表左边添加(头插法)
rpush:right push 往列表右边添加(尾插法)
lpush/rpush [key1] [value1] [value2] [value3] ...
从左到右遍历
lrange [key] [start] [end]
当end为-1 时,取出所有值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aYfLusbp-1690358602488)(./Redis.assets/image-20220905111159533.png)]
注意lrange是从左边取过去的,如果插入时使用的是lpush,则会获得相反的答案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OtqLlg4Z-1690358602492)(./Redis.assets/image-20220905110950198.png)]
lpop/rpop [key] [count]
从左边或者右边弹出一个值。count可以不加,也可以加,表示要弹出的个数。
执行:
lpop k3
可以看到lpop弹出的是第一个v1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f2xh9BI0-1690358602497)(./Redis.assets/image-20220905111841536.png)]
弹出之后,k3的v1元素消失了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tz7IC1mE-1690358602502)(./Redis.assets/image-20220905111905708.png)]
我们再执行
rpop k3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKOmMjKN-1690358602506)(./Redis.assets/image-20220905112038249.png)]
rpoplpush [key1] [key2]
将key1列表中的最右边的数push刀key2的最左边
从key1尾部取出一个节点,使用头插法插到key2列表中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXgeMAu8-1690358602511)(./Redis.assets/image-20220905145359772.png)]
lindex [key] [index]
取出列表中对应下标index的数(下标从0开始)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9tRI00Ol-1690358602515)(./Redis.assets/image-20220905145711899.png)]
llen [key]
获取列表的长度
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l8cMNl3S-1690358602520)(./Redis.assets/image-20220905145840240.png)]
linsert [key] before/after [value] [newvalue]
指定位置插入值,在key中的value值前/后插入newvalue
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qMy67J3N-1690358602524)(./Redis.assets/image-20220905150414570.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EAQn6sG3-1690358602529)(./Redis.assets/image-20220905150445921.png)]
lrem [key] [n] [value]
从左边删除n个Value
例如:删除0个v0
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GUttK1K4-1690358602534)(./Redis.assets/image-20220905150625286.png)]
lset [key] [index] [value]
将key中下表为index的元素的值,替换为value
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lBIZ0uR4-1690358602538)(./Redis.assets/image-20220905150844379.png)]
Redis Set对外提供的功能与List类似,是一个列表的功能。
其特殊之处在于set是可以自动排重(排除重复)的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择。
set提供了判断某个成员是否在一个set集合中的重要接口,这个也是list所不能提供的。
Redis 的 Set 是String类型的无序集合。它的底层其实是一个value为null的hash表,所以添加、删除、查找的复杂度都是0(1)。
O(1)是最低的时空复杂度,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。
无序集合:每次取出的顺序可能会不同
数据结构
Set数据结构是dict字典,字典是用哈希表实现的。
Java中的HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。
Redis的Set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。
sadd [key] [value1] [value2] ...
添加一个或者多个数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WAJ1Z1sO-1690358602543)(./Redis.assets/image-20220905152408313.png)]
smembers [key]
取出所有值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U50VnX01-1690358602547)(./Redis.assets/image-20220905152451232.png)]
sismember [key] [value]
判断该key中是否有value,1为真,0为假。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tuSo9M9m-1690358602552)(./Redis.assets/image-20220905152631426.png)]
scard [key]
查看set中元素的总个数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIzPGb3C-1690358602556)(./Redis.assets/image-20220905152720709.png)]
srem [key] [value1] [value2]
删除某个key中与value相同的元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cLJEcNHf-1690358602561)(./Redis.assets/image-20220905152838684.png)]
因为set是无序的,所以返回的顺序不一致。
spop [key] [count]
从该集合中随机取出一个值,取出之后,对应的元素消失
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mnZ6PTbF-1690358602566)(./Redis.assets/image-20220905153025973.png)]
注意存入的顺序和取出的顺序。
存入的顺序和取出的顺序不一致,与列表不同,所以是随机取出一个值。
随机从该集合中取出n个值,不会从集合中删除[srandmember]
srandmember [key] [n]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YasOERyl-1690358602571)(./Redis.assets/image-20220905153729110.png)]
[smove]
把集合中的某个值,移动到另一个集合
smove [key1] [key2] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SyHwDZ6F-1690358602575)(./Redis.assets/image-20220905154004198.png)]
返回两个集合的交集
sinter [key1] [key2]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kojlLbFL-1690358602580)(./Redis.assets/image-20220905154245191.png)]
返回两个集合的并集
sunion [key1] [key2]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1xJVakOm-1690358602584)(./Redis.assets/image-20220905154258324.png)]
返回两个元素的差集
sdiff [key1] [key2]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rGfq1aAS-1690358602589)(./Redis.assets/image-20220905154310040.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wcXdASsr-1690358602594)(./Redis.assets/image-20220905154313424.png)]
Redis Hash 是一个键值对集合
Redis Hash 是一个String类型的 field 和 value 的映射表,hash特别适合用于存储对象。
类似Java里面的Map
用户ID为查找的Key,存储的Value对象包含姓名、年龄、生日等信息,如果使用普通的key/value机构来存储
数据结构
Hash类型对应的数据结构有两种:ZipList(压缩列表),HashTable(哈希表)。
当field-value长度较短且个数较少时,使用ZipList,否则使用HashTable。
创建一个hash对象,给key使用value赋值
hset [key] [field] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYPb47g8-1690358602598)(./Redis.assets/image-20220906154507999.png)]
执行完成之后,key为user1,value field中有id和name属性。
user1
user1.id = 1001
user1.name = zhangsan
获取某个key的某个属性值
hget [key] [field]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QOAkJlVS-1690358602603)(./Redis.assets/image-20220906160920878.png)]
跟hset类似,可以同时设置多个field的值
hmset [key] [field1] [value1] [field2] [value2] ...
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BEoLRuiL-1690358602607)(./Redis.assets/image-20220906161129406.png)]
判断给定的key中的field是否存在
非0为真,1为true,0为false
hexists [key] [field]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GSFPNmw8-1690358602612)(./Redis.assets/image-20220906161302006.png)]
列出key中的所有field
hkeys [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-siRIuS2v-1690358602617)(./Redis.assets/image-20220906161418152.png)]
列出key的所有value
hvals [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nmaEHCx8-1690358602621)(./Redis.assets/image-20220906161443468.png)]
为hash表key中的field中的值增加一定的值
increment为增加的步长
hincrby [key] [field] [increment]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TRqqL9TJ-1690358602626)(./Redis.assets/image-20220906161741266.png)]
只有key中没有该field时,将hash表中的field值设置为value
无法覆盖原有值
hsetnx [key] [field] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QwDyK7Kp-1690358602630)(./Redis.assets/image-20220906162022376.png)]
Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(Score),这个评分被用来按照从低分到最高分的方式排序集合中的成员。
集合的成员是唯一的,但是评分可以重复。
因为元素是有序的,所以你也可以很快的根据评分或者次序来获取一个范围中的元素。
访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。
数据结构
SortedSet(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于java中Map
,可以给每个元素value赋予一个权重score 另一方面他又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过范围进行获取元素。
zset底层使用了两个数据结构:
1、hash。hash的作用就是关联数据元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
2、跳跃表。跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。
跳跃表
有序集合在生活中比较常见,例如根据成绩对学生进行排名,根据得分对玩家排名等。
对于有序集合的底层实现,可以用数组、平衡树、链表等。
数组不便元素的插入和删除。
平衡树或者红黑树虽然效率高,但是结构复杂。
链表查询需要遍历所有的元素,效率低。
Redis采用的是跳跃表,跳跃表的效率跟红黑树差不多,但是比红黑树简单。
寻找51
有序链表:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XJQUEsoa-1690358602635)(./Redis.assets/image-20220906182233393.png)]
跳跃表:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hc7oRH6d-1690358602639)(./Redis.assets/image-20220906182247303.png)]
首先是往第二层找,找到1和21,由于我们要找的是51,21后面是空,所以根据几点21进入第一层
然后21后面连接了41,41比51小,所以继续往后,而41之后是61,51比61小,所以根据41找到第0层
到达第0层之后,就可以看到41后面指向51。经过了4次查找,寻找完成。
将一个或多个member元素及其score值加入到有序集合key当中。
zadd [key] [score1] [value1] [score2] [value2] ...
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xdHjoon9-1690358602644)(./Redis.assets/image-20220906162901901.png)]
返回对应key中,满足设定范围的score对应的值。
按照从小到大排序。
zrange [key] [min] [max]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ga9dbmfL-1690358602648)(./Redis.assets/image-20220906163059329.png)]
在对应的key中,返回满足范围条件的score对应的值。(是具体的数值,不能使用-1来遍历所有的数据)
按照从大到小排序。且min和max为具体的数字。
withscores 是将分数也一起遍历
注意是先min 然后 输入max
zrangebyscore [key] [min] [max] [withscores] [limit offset count]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VQNWGU8k-1690358602653)(./Redis.assets/image-20220906173929352.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J6WRKWAN-1690358602658)(./Redis.assets/image-20220906173947514.png)]
withscores
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O3mGeeBv-1690358602662)(./Redis.assets/image-20220906174412050.png)]
返回所有score介于min和max之间(包括min或者max)的成员。
有序集合按score值递增**(从大到小)**排序。
注意是先max,后min
zrevrangebyscore [key] [max] [min] [withscores] [limit offset count]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vX5W8NAh-1690358602667)(./Redis.assets/image-20220906175127045.png)]
为元素的score加上增量
zincrby [key] [increment] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-roYuGOjh-1690358602671)(./Redis.assets/image-20220906180039329.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZOCu6Idd-1690358602676)(./Redis.assets/image-20220906180045443.png)]
然后为java添加50的score
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lMhafHJw-1690358602680)(./Redis.assets/image-20220906180758267.png)]
然后可以看到java排到了最后
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TthgesqV-1690358602685)(./Redis.assets/image-20220906180921872.png)]
删除该集合下,指定值的元素
zrem [key] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0lv58LGL-1690358602689)(./Redis.assets/image-20220906181033406.png)]
统计区间中的所有元素个数
zcount [key] [min] [max]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TkEuf7SA-1690358602694)(./Redis.assets/image-20220906181117241.png)]
返回该值在集合中的排名,从0开始
zrank [key] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7pDkDguV-1690358602699)(./Redis.assets/image-20220906181238967.png)]
https://blog.csdn.net/qq_19007335/article/details/124885668
需要更改的地方:1、注释 bind 2、更改protected-mode为no
配置大小单位,开头定义了一些基本的度量单位,只支持byte,不支持bit
大小写不敏感
################################## INCLUDES ###################################
# Include one or more other config files here. This is useful if you
# have a standard template that goes to all Redis servers but also need
# to customize a few per-server settings. Include files can include
# other files, so use this wisely.
#
# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
# from admin or Redis Sentinel. Since Redis always uses the last processed
# line as value of a configuration directive, you'd better put includes
# at the beginning of this file to avoid overwriting config change at runtime.
#
# If instead you are interested in using includes to override configuration
# options, it is better to use include as the last line.
#
# include /path/to/local.conf
# include /path/to/other.conf
配置包含、引入的其它配置文件
在这里引入一个或者多个配置文件。如果你有标准的配置模板的话会非常有用,可以将标准的模板配置到所有的Redis服务器上,并为每个单独的服务器配置少量的配置。
引入的文件中可以引入其他的文件,所以需要明智的使用。
要注意Include属性不会管理员或者Redis Sentinel的“config rewrite”命令重写。Redis总是使用最后处理的行作为配置指令的值,你最好将include放在文件的头部,避免在运行时配置文件的重写和更改。
################################## NETWORK #####################################
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
# 默认情况下,如果“bind"未被明确指定,Redis会监听此 服务器来自所有可用的网络接口的连接。
# 可能
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 loopback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#bind 127.0.0.1
# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
# "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode no
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379
# TCP listen() backlog.
#
# In high requests-per-second environments you need an high backlog in order
# to avoid slow clients connections issues. Note that the Linux kernel
# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
# in order to get the desired effect.
tcp-backlog 511
# Unix socket.
#
# Specify the path for the Unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /tmp/redis.sock
# unixsocketperm 700
# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0
# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
# equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 300 seconds, which is the new
# Redis default starting with Redis 3.2.1.
tcp-keepalive 300
网络部分,配置网络
默认情况bind=127.0.0.1只能接受本机的访问请求
不写的情况下,无限制接收任何IP地址的访问
在生产环境下,需要写你应用服务器的地址。
服务器是需要远程访问的,所以需要注释掉。
如果开启了protected-mode,那么在没有设定bind ip且没有设置密码的情况下,redis只允许接收本机的响应
protected yes/no
port 6379
端口号,默认为6379
tcp-backlog 511
设置tcp的back-log,back-log其实是一个连接队列,back-log队列总和=未完成三次握手的队列+已经完成三次握手的队列。
在高并发环境下,你需要一个高back-log值来避免客户端连接问题。
注意Linux内核会将这个值减少到 /proc/sys/net/core/somaxconn 的值(128),所以需要确认增大 /proc/sys/net/core/somaxconn 和 /proc/sys/net/ipv4/tcp_max_syn_backlog 的值(128),需要增大这两个值来达到想要的效果。
timeout 0
设置超时时间,以秒为单位。
tcp-keepalive 300
保存连接时间,如果长时间(单位:秒)没有操作,则会释放连接。
################################# GENERAL #####################################
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
# daemonize yes
# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
# supervised no - no supervision interaction
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous liveness pings back to your supervisor.
supervised no
# If a pid file is specified, Redis writes it where specified at startup
# and removes it at exit.
#
# When the server runs non daemonized, no pid file is created if none is
# specified in the configuration. When the server is daemonized, the pid file
# is used even if not specified, defaulting to "/var/run/redis.pid".
#
# Creating a pid file is best effort: if Redis is not able to create it
# nothing bad happens, the server will start and run normally.
pidfile /var/run/redis_6379.pid
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile ""
# To enable logging to the system logger, just set 'syslog-enabled' to yes,
# and optionally update the other syslog parameters to suit your needs.
# syslog-enabled no
# Specify the syslog identity.
# syslog-ident redis
# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
# syslog-facility local0
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT where
# dbid is a number between 0 and 'databases'-1
databases 16
# By default Redis shows an ASCII art logo only when started to log to the
# standard output and if the standard output is a TTY. Basically this means
# that normally a logo is displayed only in interactive sessions.
#
# However it is possible to force the pre-4.0 behavior and always show a
# ASCII art logo in startup logs by setting the following option to yes.
always-show-logo yes
daemonize
是否为后台进程,默认为yes
守护进程,后台启动
存放pid文件的位置,每个实例会产生一个不同的pid文件
pidfile /var/run/redis_6379.pid
表示日志级别
loglevel notice/debug/verbose/warning
debug (a lot of information, useful for development/testing)
Debug (大量的信息,对开发和测试非常有帮助)
verbose (many rarely useful info, but not a mess like the debug level)
Verbose (一些少量有用的信息,但是不像Debug一样杂乱)
notice (moderately verbose, what you want in production probably)
Notice(moderately 适量长度,大概是你在生产环境中想要的信息)
warning (only very important / critical messages are logged)
Warning(只有特别重要/关键的信息会被打印到日志)
设置日志的输出目录,默认为空
logfile ""
设置数据库的数量,默认是16个
database 16
################################## SECURITY ###################################
# Require clients to issue AUTH before processing any other
# commands. This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
# requirepass 111111
# Command renaming.
#
# It is possible to change the name of dangerous commands in a shared
# environment. For instance the CONFIG command may be renamed into something
# hard to guess so that it will still be available for internal-use tools
# but not available for general clients.
#
# Example:
#
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#
# It is also possible to completely kill a command by renaming it into
# an empty string:
#
# rename-command CONFIG ""
#
# Please note that changing the name of commands that are logged into the
# AOF file or transmitted to replicas may cause problems.
访问密码的查看、设置和取消
#requirepass foobared
默认没有密码,此行被注解
在命令中设置密码是暂时的,重启redis服务器之后,密码就会被还原
而在文件中设置的密码是永久的,每次启动服务器都需要。
config get requirepass
config set requirepass "123456"
auth 123456
设置redis同时可以与多少个客户端进行连接
默认情况下可为10000个客户端
如果达到了此限制,redis则会拒绝新的连接请求,并且向这些连接请求方发出“max number of client reached”作为回应。
#maxclients 10000
建议必须设置,否则内存占满会导致服务器宕机
设置redis可以使用的内存大小。
一旦内存使用达到上线,redis便会试图移除内部数据,移除规则可以通过 maxmemory-policy 来指定。
用来设置内存满时,redis对内部数据删除的策略
volatile-lru:使用LRU算法移除key,只对设置了过期时间的键;(最近最少使用)
allkeys-lru:在所有集合key中,使用LRU算法移除key;
volatile-random:在过期的集合中,随机删除key,只对设置了过期时间的key
allkeys-random:在所有集合的key中,随机删除key
volatile-ttl:移除那些TTL值最小的key(最近要过期的key)
noeviction:不进行移除。(针对写操作,只返回错误信息)
设置样本数量。
LRU算法和最小TTL算法都并非是精确算法,而是一个估算值,所以可以设置样本的大小,redis会去检查样本数量的key并选择需要淘汰哪一个。
一般设置3-7个样本即可,数字越小样本越不准确,同样的性能损耗也会变小。
Redis发布/订阅(pub/sub)是一种消息通信模式。【publish:发布/subscribe:订阅】
发送者发送消息,订阅者接收消息。
Redis客户端可以订阅任意数量的频道。【频道】有点类似观察者模式
1、打开一个客户端,订阅channel1
SUBSCRIBE channel1
2、打开另一个客户端,给channel1发布消息hello
publish channel1 hello
3、打开第一个客户端可以看到发送的消息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-58YuyV4Q-1690358602703)(./Redis.assets/image-20220907163031712.png)]
发布的信息没有持久化,如果在订阅的客户端收不到hello,只能收到订阅后发布的消息。
BitMaps本身不是一种数据类型,实际上他只是一个字符串(key-value),但是它可以对字符串的位进行操作。
BitMaps单独提供了一套操作命令,可以把BitMaps看做以位为单位的数组,且这个数组只能存储0和1,数组的下标在BitMaps中叫做偏移量。
key [0,1,0,1,0,0,0,0,1,0,1,0,1,0]
设置bitmaps中某个偏移量的值(offset:偏移量,从0开始)
setbit [key] [offset] [value]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p2m5uvak-1690358602708)(./Redis.assets/image-20220907163807183.png)]
很多应用的用户ID以一个指定的数字(例如10000)开头,直接将用户ID和BitMaps的偏移量进行对应势必会造成一定的浪费,通常的做法是将每次做setbit操作时,将用户id减去这个指定的数字。
在第一次初始化BitMaps时,假如偏移量特别大,那么整个初始化执行过程会比较慢,可能会造成阻塞。
获取BitMaps中某个偏移量的值。(偏移量从0开始算,默认为0)
getbit [key] [offset]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JJtfS9pE-1690358602712)(./Redis.assets/image-20220907164128465.png)]
统计字符串被设置为1的bit数。
一般情况下,给定的整个字符串都会被进行计数,通过指定额外的start或者end参数,可以让计数在指定的范围内进行。
start和end参数的设置都可以使用负数值如:-1 表示最后一个位,-2表示倒数第二个位
start、end也会被包含在内。
bitcount [key] [start end]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jqBZmnJb-1690358602717)(./Redis.assets/image-20220907164412587.png)]
是以字节为单位,并非为位
举例:
viewer [01000001 01000000 00000000 00100001]
bitcount viewer 1 2
统计下标为1、2字节组中bit=1的个数,即[01000000 00000000]中1的个数=1
返回1
bitcount viewer 1 3
统计下标为1到下标为3中bit=1的个数,即[01000000 00000000 00100001]中1的个数=3
返回3
bitcount viewer 0 -2
统计下标为0开始到下标倒数第二个字节中bit=1的个数,即[01000001 01000000 00000000]中1的个数=3
返回3
Redis中setbit设置或者清除的是以bit为单位,而bitcount计算的是以byte为单位
bitop是一个复合操作,可以做多个BitMaps的 and(交集)、or(并集)、not(非)、xor(异或)等操作并将结果保存在destkey中。
bitop and/or/not/xnot [destkey] [bitmap1] [bitmap2]
举例:
20201104访问的用户:
setbit unique:users:20201104 1 1
setbit unique:users:20201104 2 1
setbit unique:users:20201104 5 1
setbit unique:users:20201104 9 1
20201103访问的用户:
setbit unique:users:20201103 0 1
setbit unique:users:20201103 1 1
setbit unique:users:20201103 4 1
setbit unique:users:20201103 9 1
1、计算出两天都访问过的用户数量:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iPEOgFTQ-1690358602721)(./Redis.assets/image-20220907170420833.png)]
127.0.0.1:6379> bitop and bothviewer unique:users:20201103 unique:users:20201104
(integer) 2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nWrTKiZr-1690358602726)(./Redis.assets/image-20220907170506832.png)]
可以看到,两天都访问过的用户有1和9共2位用户。
2、计算出任意一天都访问过网站的用户数量(例如月活跃度),可以使用or求并集
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kz9U7TRH-1690358602731)(./Redis.assets/image-20220907170803376.png)]
127.0.0.1:6379> bitop or activekey unique:users:20201104 unique:users:20201103
(integer) 2
127.0.0.1:6379> bitcount activekey
(integer) 6
127.0.0.1:6379>
假设有1亿用户,每天独立访问用户有五千万,如果每天用集合类型和BitMaps分别存储活跃用户可以得到表:
数据类型 | 每个用户id占用空间 | 需要存储的用户量 | 需要的内存量 |
---|---|---|---|
集合类型 | 64位 | 5000 0000 | 64*5000 0000=400mb |
BitMaps | 1位 | 1 0000 0000 | 1*1 0000 0000=12.5mb |
数据类型 | 一天 | 一个月 | 一年 |
---|---|---|---|
集合 | 400mb | 12gb | 144gb |
BitMaps | 12.5mb | 375mb | 4.5gb |
但是BitMaps并不是万金油,加入该网站每天独立访问的用户很少,例如只有10w,那么两者的对比如下,很显然这时候使用bitmaps就不太合适了,因为基本上大部分位都是0
数据类型 | 每个用户id占用空间 | 需要存储的用户量 | 需要的内存量 |
---|---|---|---|
集合类型 | 64位 | 10 0000 | 64*10 0000=800kb |
BitMaps | 1位 | 1 0000 0000 | 1*1 0000 0000=12.5mb |
在工作当中我们经常会遇到与统计相关的功能需求,比如统计网站的PV(pageView页面访问量),可以使用Redis的incr,incrby轻松实现。
但是像UV(UniqueVisitor,独立访客)、独立IP数、搜索记录等需要去重和技术的问题如何解决?
这种求集合中不重复元素个数的问题称为基数问题。
Redis HyperLogLog是用来做基数统计的算法。HyperLogLog的优点是,在输入元素的数量或者体积非常大时,计算基数所需的空间总是固定的,并且是很小的。
在Redis里,每个HyperLogLog键只需要花费12kb的内存,就可以计算接近2的64次方个不同元素的基数。
HyperLogLog只会根据输入元素来进行计算基数,而不会存储输入元素本身,所以HyperLogLog不能像集合那样返回输入的各个元素。
什么是基数?
举例:
数据集{1,2,2,3,4,7,8,9,9,9,9}
则基数集为{1,2,3,4,7,8,9},基数为7。
基数估计就是在误差可接受的范围内,快速计算基数。(可以去掉重复的)
添加指定元素到HyperLogLog
pfadd [key] [element] [element]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MA8oFglJ-1690358602735)(./Redis.assets/image-20220913132942979.png)]
是取基数,所以在添加重复的对象时会失败。
如果执行之后HLL估计的近似基数发生变化则会返回1,否则返回0。
计算HLL的近似基数,可以计算多个HLL,比如用HLL存储每天的UV
pfcount [key]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tGR7aQiE-1690358602740)(./Redis.assets/image-20220913135337580.png)]
合并
总的来说就是用一个新的key来存放两个key的并集
pfmerge [destkey] [sourcekey1] [sourcekey2] ...
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WHHHG4N7-1690358602744)(./Redis.assets/image-20220914102543044.png)]
Redis3.2中增加了对GEO类型的支持。
GEO,Geographic,地理信息
该类型就是元素的二维坐标,在地图上的经纬度。redis基于该类型提供了经纬度设置、查询、范围查询、距离查询、经纬度hash等常见操作。
添加一个或者多个地区的坐标和名称
longitude 经度
latitude 纬度
member 名称
geoadd [key] [longitude] [latitude] [member] ...
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VnyxdAID-1690358602749)(./Redis.assets/image-20220914103247183.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2z1aePZx-1690358602753)(./Redis.assets/image-20220914103252172.png)]
两极无法直接添加,一般会下载城市数据,通过java一次性导入。
有效的经度从-180到180。
有效的纬度从-85.05112878 到 85.05112878
当坐标位置超出指定范围时,该命令将会返回一个错误。
已经添加的数据,是无法再次往里面添加的。
获取指定地区的坐标值
浮点数有经度丢失
不存在的返回 nil。
geopos [key] [member] [menber] ...
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9883oaWJ-1690358602758)(./Redis.assets/image-20220914103616925.png)]
获取两个坐标点之间的直线距离
geodist [key] [member1] [member2] ...[m|km|ft|mi]
m表示单位为米
km表示单位为千米
mi表示单位为英里
ft表示单位为英尺
如果用户没有指定单位参数,默认为m米。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hBzX5bi-1690358602762)(./Redis.assets/image-20220914104408973.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WbynJkPK-1690358602767)(./Redis.assets/image-20220914104528502.png)]
以给定的经纬度为中心,找出某一半径内的元素
georaduis [key] [longitude] [latitude] raduis [m|km|ft|mi]
longitude 经度
latitude 纬度
raduis 半径距离
[m|km|ft|mi] 单位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ys8PHTKq-1690358602771)(./Redis.assets/image-20220914104735686.png)]
类似于JDBC,Jedis是Redis提供给java的一个接口工具,可以使用java控制redis。
1.创建maven项目
2.引入相关依赖:
redis.clients
jedis
4.2.3
3.准备Redis镜像
docker run命令:https://www.runoob.com/docker/docker-run-command.html
docker run -itd --name myredis -p 6379:6379 redis//将对应的端口映射到本机
//itd: -i 以交互模式运行容器,-t: 为容器重新分配一个伪输入终端,-d: 后台运行容器,并返回容器ID;
docker ps //查看运行中的镜像
docker exec -it [name] bash //测试是否能进入redis镜像
5.使用命令行,开启端口映射,开启镜像
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9lKp8FBf-1690358602776)(./Redis.assets/image-20220914131243455.png)]
bind 127.0.0.1 # 注释掉这部分,这是限制redis只能本地访问 7.0版本及以上改为默认注释掉了,不用手动注释
protected-mode no # 默认yes,开启保护模式,限制为本地访问
daemonize no # 默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
databases 16 # 数据库个数(可选)
dir ./ # 输入本地redis数据库存放文件夹(可选)
appendonly yes # redis持久化(可选)
Linux 关掉系统防火墙(不推荐):
systemctl stop firewalld
systemctl status firewalld
推荐:可以直接开放6379端口,但是要小心端口攻击(开启后记得重启redis)
*阿里云服务器需要在安全组中设置6379端口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRDFI39e-1690358602780)(./Redis.assets/image-20220914133058990.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2EZWrxJp-1690358602785)(./Redis.assets/image-20220914131644525.png)]
如果这里显示的是如上图所示的样子,则成功开启了端口映射。
6.写测试代码
package org.lobo;
import redis.clients.jedis.Jedis;
public class Main {
public static void main(String[] args) {
//创建Jedis对象,参数是host和port
Jedis jedis=new Jedis( "127.0.0.1",6379);
//测试
String ping = jedis.ping();
System.out.println(ping);
}
}
7.运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FqIdS6Sq-1690358602789)(./Redis.assets/image-20220914132831910.png)]
既然已经连接好了Redis,现在可以通过java来使用Jedis操作redis了。
在操作之前,我们先进行一次清除数据库内的数据:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JlzC7NTK-1690358602794)(./Redis.assets/image-20220914133612080.png)]
在java中添加以下语句
jedis.setnx("k1","v1");
jedis.setnx("k2","v2");
jedis.setnx("k3","v3");
然后我们再回到redis中通过keys *查看所有的key
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JV1bp8oN-1690358602799)(./Redis.assets/image-20220914133817454.png)]
继续进行测试:
//创建Jedis对象,参数是host和port
Jedis jedis=new Jedis( "127.0.0.1",6379);
//测试
String ping = jedis.ping();
System.out.println(ping);
//设置非重复key-value
jedis.setnx("k1","v1");
jedis.setnx("k2","v2");
jedis.setnx("k3","v3");
//查询所有的key
Set<String> keys = jedis.keys("*");
System.out.println("keys.size()="+keys.size());
System.out.println("keys * =");
for (String key:keys){
System.out.println(key);
}
//查询key的属性
System.out.println("jedis.exists(\"k1\")="+jedis.exists("k1"));
System.out.println("jedis.ttl(\"k1\")="+jedis.ttl("k1"));
System.out.println("jedis.get(\"k1\")="+jedis.get("k1"));
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-thwqT1wM-1690358602803)(./Redis.assets/image-20220914134229971.png)]
//设置多个key-value
jedis.mset("key1","value1","key2","value2");
List<String> mget = jedis.mget("key1", "key1");
System.out.println(mget);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QFzGmxCM-1690358602808)(./Redis.assets/image-20220920103007098.png)]