Redis是一种非关系型数据库。底层采用聚合数据结构存储数据 。C语言编写的,基于内存运行的高性能数据库。
Redis中的数据大部分时间都存储在内存中。适合存经常访问的,数据量小的。
特点:
1、支持数据持久化
2、支持多种数据结构:不仅支持k-v,同时还支持list,set,zset,hash等数据结构。
3、支持数据备份
前台启动:任何目录下执行redis-server
后台启动:任何目录下执行redis-server &
启动Redis服务时指定配置文件:redis-server redis.config &
配置文件是,安装目录redis-x.x.x 文件夹里的redis.config
1、通过kill命令直接关闭,暴力,什么进程都能关
步骤:
ps -ef|grep redis查看pid
kill -9 pid
2、通过redis命令关闭:redis-cli命令,redis-cli shutdown
Redis客户端通过网络连接Redis服务器,从而实现根Redis服务器的交互。客户端发送命令并显示Redis服务器执行的结果。
启动Redis客户端:redis-cli
(默认ip127.0.0.1 端口号6379)
指定端口号:redis-cli -p 端口号
指定ip和端口号:redis-cli -h ip -p 端口号
关闭Redis客户端:exit
或者quit
1、测试redis 服务性能:任意目录下执行redis-benchmark
2、查看redis服务是否正常运行:ping
如果正常就返回pong
3、查看redis服务器的统计信息:info
查看指定信息段:info [信息段]
作用类似于mysql的数据库实例,但是redis中数据库实例只能由redis服务来创建和维护,开发人员不能修改和自行创建。
默认redis刚启动就自动创建16个,给16个数据库实例进行编号0~15;可以通过配置文件指定redis自动创建的数据库个数。redis每个数据库实例本身占用的存储空间很少,不会造成存储空间大量浪费。
默认情况下,redis客户端连接的是编号0的数据库。
0、存数据:set key value
1、切换数据库:select 编号
2、取值:get key
3、查看数据库中key的数目:dbsize
注:旧版本中,0号数据库,默认会有4个key-value,
查看数据库中有哪些key:keys *
4、清空数据库实例:flushdb
5、清空所用数据库的实例:flushall
6、查看redis中的所有配置信息:config get *
查看redis中的某一项配置信息:config get 某项信息
string 单key,单value:用于存放字符串
list, 单key,多有序value:用于存放list列表
set 单key,多无序value:用于set集合
hash 单key,对象(属性:值):用于存放java对象pojo
zset 单key,多排序value(根据参考值排序)
1、keys pattern
作用:查找所有符合模式pattern的key,pattern可以使用通配符
例如:keys * :查看所有key
注:*匹配0个或多个字符;?匹配1个字符 ;[ ] 匹配一个字符,并且是[ ]内的一个字符
2、exists key
作用:判断指定key是否在数据库中已存在,存在则返回1;不存在返回0
例如:exists k1 [k2 k3 k4 …] 返回值是存在key的个数
3、move key index
作用:移动指定key到指定数据库实例index
4、ttl key
作用:查看指定key的剩余生存时间。key不存在则返回-2,key没有设置生存时间则返回-1
5、expire key 时间
作用:设置key的最大生命时间,时间以秒为单位
6、type key
作用:查看指定key数据类型
7、rename key 新key
作用:重命名key
8、del key [key key key …]
作用:删除指定key,返回值是删除key的数量。
1、set key value
将string类型数据存储进redis中,重复key会覆盖
2、get key
从redis中获取string类型数据
3、append key extravalue
追加字符串,返回追加的长度
4、strlen key
获取字符串数据的长度
5、incr key
将字符串数据进行 +1 运算,返回 +1 运算后的数据,如果不存在key则先设置一个key初始化值为0,在运算。
要求key表示的value必须是数值,否则报错
decr key
将字符串数据进行 -1 运算
6、incrby key offset
将字符串数值进行加offset运算
例如 incrby age 10
decrby key offset
7、getrange key startIndex endIndex
获取字符串中的子串,从startIndex 到endIndex 的字符组成的子串。下标从0开始。截取是闭区间。数据库原本的值不会改动。
下标为负的是,自右至左,从-1开始
例如:getrange name 0 -1 :表示全部截取
8、setrange key startIndex value
用value覆盖从下标startIndex开始的字符串,返回修改后字符串长度,如果value不足够覆盖原本后面的,那原本后面的就不改变。覆盖几个算几个。
9、setex key seconds value
设置字符串数据的同时设置它的最大生命周期
10、setnx key value
把string 数据存入redis,当key不存在时设置成功,否则放弃设置
11、mset k1 v1 k2 v2 k3 v3 …
批量设置key-value,
12、mget k1 k2 …
批量获取string类型的数据
13、msetnx
批量设置字符串,所有key都不存在时设置成功,只要有一个存在,就失败
单key,多有序value
value之间是有序的,由放入顺序决定。从左往右0…n-1 ,从右往左-1…-n
通过key和下标操作数据
1、lpush key v1 v2 v3 …
将一个或多个值依次插入列表表头。插入完成之后是逆序。
返回值是存入value个数
2、lrange key startIndex endIndex
获取指定列表中元素
例如:lrange list1 1 2
3、rpush key v1 v2 …
将一个或多个值插入列表表尾。插入完成之后是顺序。
4、lpop key
指定列表key删除并返回表头元素。
rpop key
指定列表key删除并返回表尾元素。
5、lindex key index
获取列表key指定下标index的元素。
6、llen key
获取指定列表key长度
7、lremove key [count] value
指定列表key移除和value相同的数据,count表示移除多少个,count大于0从左侧,count小于0从右侧,count=0就是移除所有
8、ltrim key startIndex endIndex
截取指定下标区间的元素组成新的列表
9、lset key index value
指定下标元素设置为指定值
10、linsert key before/after pivot value
将value插入到指定列表位于pivot元素之前./之后的位置
单key,多无序value。
通过key确定集合,直接操作业务数据和数据个数
1、sadd key v1 v2 v3
将一个或多个元素添加到集合key中,返回添加的个数
2、smembers key
获取指定集合所有元素
3、sismember key member
判断元素member是否在集合key中,存在返回1,否则返回0
4、scard key
获取集合key长度
5、srem key v1 v2 …
删除集合中的一个或多个元素,不存在元素会被忽略,返回删除个数。
6、srandmember key [count]
随机获取集合key中的count个元素(默认一个),count>0 不重复,count<0 可能重复。返回获取元素
7、spop key [count]
随机移除指定集合key的一个或多个元素,返回移除元素
8、smove source dest member
将指定集合source的指定元素member移动到另一个集合dest
9、sdiff key k2 k3 k4 …
集合的差集,返回
10、sinter k1 k2 k3 k4…
获取所有集合都有的元素
11、sunion k1 k2 k3 k4 …
获取所有集合所有元素
单key:多field- value
1、hset key field1 value1 field2 value2 field3 value3 …
将一个或多个field-value存入哈希表key中
2、hget key field
获取指定哈希表key中指定field的值
3、hmset key field1 value1 field2 value2 field3 value3 …
批量设置多个
4、hmget key field1 field2 field3 field4…
批量获取指定哈希表key的过多field的值
5、hgetall key
获取哈希表key所有的field value
6、hdel key field1 field2 field3 …
从哈希表key删除一个或多个field
7、hlen key
获取哈希表key所有的field的个数
8、hexists key field
判断指定哈希表key是否存在某域,存在则返回1
9、hkeys key
获取哈希表key所有与field列表
10、hvals key
获取哈希表key所有与value列表
11、hincrby key field int
对哈希表key的某field值进行加int运算
12、hincrby key field float
对哈希表key的某field值进行加float运算
13、hsetnx key field value
将一个field value设置到哈希表key中,当且仅当field不存在时
有序集合zset不允许重复成员,每个元素会关联一个分数(分数可以重复),redis通过分数来为集合中的成员排序。
有序集合中每个元素都有
1、zadd key score1 member1 score2 member2 …
一个或多个元素member及其分数score加入zset集合key
2、zrange key startIndex endIndex [withscores]
获取有序集合key中指定下标区间的元素,加上withscores就会再显示分数
3、zrangebyscore key min max [withscores]
获取有序集合key指定分数区间(闭区间)的元素,加上withscores就会再显示分数
4、zrem key member1 member2…
删除有序集合key中一个或多个元素
5、zcard key
获取集合key所有元素个数
6、zcount key min max
获取集合key分数在指定区间(闭区间)的元素个数
7、zrank key member
获取指定有序集合key中元素member排名,排名从0开始
8、zscore key member
获取集合key中指定元素member的分数
9、zrevrank key member
获取指定有序集合key中元素member反向排名(从大到小),排名从0开始
port:指定redis服务所使用的端口,默认6379
bind:配置客户端连接redis时,使用的IP地址,默认可以使用redis服务所在主机上的任意一个ip;一般情况下都会配置一个ip,通常是一个真实ip。
tcp-keepalive:连接保活策略
如果配置了port和bind,则客户端连接和关闭redis服务的时候必须指定IP和端口
reids-cli -h ip -p port
redis-cli -h ip -p port shutdown
loglevel:配置日志级别
logfile:指定日志文件。redis在运行过程中输出日志信息,默认输出到控制台,可以使用logfile配置日志文件,使redis把日志信息输出到指定日志文件。
database:配置数据库数量
requirepass:配置访问Redis服务时使用的密码,默认不使用。此参数必须在protected-mode=yes时才起作用。
一旦设置了密码,客户端连接redis时,必须redis-cli -h ip -p port -a pwd
默认:1分组1万次,5分钟10次,15分钟1次。
配置文件中:
save 900 1
save 300 10
save 60 10000
Redis持久化策略,在适当时机采用适当策略把内存中的数据持久化到磁盘中看,每次redis服务启动时都可以把磁盘上的数据再次加载到内存中。
在指定时间间隔内,redis服务执行指定次数的写操作,会自动触发持久化操作。
采用操作日志记录每一次写操作,每次redis服务启动后,都会重新执行一遍操作日志中的指令。
相比于RDB,AOF降低了效率。
小结:根据数据特点选择策略,一般情况使用RDB,特别重要就都开启。
事务:把一组数据库放在一起执行,保证操作原子性,要么同时成功,要么同时失败。
Redis事务,允许把一组Redis命令放在一起执行,把命令进行序列化,然后一起执行,只能保证部分原子性。
1、multi
标记一个事务的开始,开启之后,操作命令会压入一个队列。
2、exec
执行事务队列中的所有命令。
3、部分原子性:
a、如果一组命令,有的在压入队列过程中就发生了错误的命令(如指令格式错误),则本事务所有命令都不执行,能保证事务的原子性。
b、如果一组命令,在压入队列时正常,但是在执行过程中发生了错误,则只会影响发生错误的命令,不会影响其他命令。不能保证事务的原子性。
4、discard
清除所有已经压入队列中的命令。并结束multi
5、watch
监控一个或多个键,当事务在执行过程中,此键代表的值发生变化,则本事务放弃执行;否则正常执行。
例如:set balance 50
set balance2 100
set version 1
watch version
multi
incr version
decrby balance 50
incrby balance2 50
exec
6、unwatch
放弃监控某一个键,例如满足一定条件放弃监控
watch version
unwatch version
multi
incr version
decrby balance 50
incrby balance2 50
exec
redis客户端订阅消息,消息的发布者王频道发布消息,所有订阅者客户端能够接受消息。
1、subscribe:订阅一个或多个频道消息
subscribe 频道
2、publish:将消息发布到频道
publish 频道 信息
3、psubscribe:订阅一个或多个频道消息,频道名支持通配符
subscribe 频道*
主机数据更新后根据配置和策略,自动同步到从机的master/slave机制,master以写为主,slave以读为主。
1、搭建三台redis服务
提供三个redis配置文件:redis6379.conf、redis6380.conf、redis6381.conf
修改三份配置文件:以redis6379.conf为例
port改为6379
pidfile改为端口名一致
logfile改为端口名一致的
dbfilename 端口名一致
分别使用三个redis文件启动三个redis服务,分别用三个终端
redis-server redis6379.conf &
redis-server redis6380.conf &
redis-server redis6381.conf &
2、通过redis客户端连接redis客户端
redis-cli -p 端口号
3、查看三台redis服务在集群中的主从角色
info replication
4、6379执行写操作
set k1 v1
5、设置主从关系,设从不设主
6380上执行 slaveof 127.0.0.1 6379
6381上执行 slaveof 127.0.0.1 6379
6、全量复制:一旦主从关系确定,会自动把主库上已有的数据同步到从库
7、增量复制:主库上写数据会自动同步到从库
8、主写从读,读写分离
在6380和6381上执行set操作,不能执行。
9、主机宕机:从机原地待命,只能读 数据不会再更新
关闭6379服务
查看6380和6381上的主从角色,还是slave,但是连接状态变成down
10、主机恢复:一切恢复正常
重启6379,redis-server redis6379.conf &
11、从机宕机:缺少一个从机,其他不变
关闭6380服务
12、从机恢复:需要重新设置主从关系
13、从机上位
a、主机6379宕机,从机原地待命
b、从机6380断开原来的从属关系:
6380上执行 slave no one
c、重新设置主从关系
6381上执行slaveof 127.0.0.1 6380
14、原主机又修好了:从属于新主机
a、重启6379
b、再6379上执行:slaveof 127.0.0.1 6381
注:从机可以有从机,只要有从的角色就不能写
主机宕机、从机自动上位。
1、搭建一主二从集群环境
2、通过redis客户端连接redis客户端
redis-cli -p 端口号
3、查看三台redis服务在集群中的主从角色
info replication
4、6379执行写操作
set k1 v1
5、设置主从关系,设从不设主
6380上执行 slaveof 127.0.0.1 6379
6381上执行 slaveof 127.0.0.1 6379
6、部署哨兵监控主机
提供哨兵配置文件:在redis安装目录下,创建redis_sentinel.conf,编辑内容:
sentinel monitor dc-redis 127.0.0.1 6379 1
表示:指定监控主机的ip 端口号 得到哨兵的票数
7、启动哨兵服务
(新终端中启动)
redis-sentinel redis_sentinel.conf
之前的主机恢复,自动从属于新的主机。
新的主机宕机之后,会自动再选新主机。
在Java应用中操作Redis。Jedis几乎涵盖了所有Reids命令,操作Redis命令在Jedis中以方法的形式出现。
创建maven项目,加入jedis依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.0.1</version> </dependency>
测试程序
package com.daihan.jedis; import redis.clients.jedis.Jedis; import java.util.Set; public class keyTest { public static void main(String[] args) { //连接Redis, Jedis jedis=new Jedis("192.168.244.131",6379); //使用jedis对象操作Redis //String ping=jedis.ping(); //System.out.println(ping); Set<String> keys=jedis.keys("*"); for(String key:keys){ System.out.println(key); } } }
public class keyTest { public static void main(String[] args) { //连接Redis, Jedis jedis=new Jedis("192.168.244.131",6379); //获取事务对象 Transaction tran=jedis.multi(); //接下来用tran调方法执行redis命令 tran.set("k2",v2); tran.set("k3",v4); tran.exec(); } }