redis是一种数据库,是存储数据、管理数据的软件 nosql数据库 非关系型数据库,采用聚合数据结构存储数据 //聚合结构:k-v
根据数据不同的特点选不同的数据库
MySQL是关系型数据库, 采用关系数据模型:维护表与表的关系
BSON:数据保存在键值对中,数据与数据采用逗号隔开,{ }表对象 [ ]表数组
{
"student":{
"id":1001,
"name":"zhangsan",
"addresses":{"province":"beijing","city":"daxingqu","street":"liangshuihe"},
"courses":[
{
"id":01,
"name":"java"
},
{
"id":02,
"name":"mybatis"
},
{
"id":03,
"name":"spring"
}
]
}
}
redis基于内存并支持持久化,其中的数据大部分时间存储在内存,所以访问很快,适合存储访问频繁,数据量小的数据 //所以又叫缓存数据库
Redis的特点
安装:
下载Linux安装包。传输过去,解压到opt下
在redis根目录下,编译redis,进入解压目录,并且执行make命令:make
报错:gcc命令未找到:安装gcc yum -y install gcc //查看查看Linux内核版本:gcc –v
清理上次make产生的文件:make distclean //然后再make命令
执行make install安装redis 并且把redis的命令放到环境变量中
后台启动redis服务:redis-server &
端口号
启动redis服务时,指定配置文件: //可以控制redis服务运行中的一些参数,如端口号等,没有使用配置文件使用默认参数
redis-server redis.conf &
关闭redis服务:redis-cli shutdown
使用redis:redis的客户端:用来连接redis服务,向redis服务端发送命令,并且显示redis服务处理结果。
redis-cli:是redis自带客户端,使用命令redis-cli就可以启动redis的客户端程序。 //默认连接127.0.0.1本机的6379端口上的redis服务
1)连接客户端: redis-cli
redis-cli -p 端口号 //连接127.0.0.1本机的指定端口号上的redis服务
redis-cli –h IP地址 -p 端口号 //连接指定主机的指定端口号上的redis服务
2)退出客户端:quit
基本知识:
redis-benchmark:命令,测试redis性能 //启动redis后可以测试
连接客户端之后使用 :
Redis沟通命令,查看状态://redis给我们返回PONG,表示redis服务运行正常
查看redis服务器的统计信息:info 、 info 信息段 //查看指定信息段的信息
redis的数据库实例:作用类似于mysql的数据库实例
不同:redis中的数据库实例只能由redis服务来创建和维护,开发人员不能修改和自行创建数据库实例;
默认情况下,redis会自动创建16个数据库实例,并且给这些数据库实例进行编号,从0~15,使用时通过编号来使用数据库;
可以通过配置文件,指定redis自动创建的数据库个数;redis的每一个数据库实例本身占用的存储空间是很少的,所以也不造成存储空间的太多浪费。
默认情况下,redis客户端连接的是编号是0的数据库实例;
切换数据库实例:select 编号查看当前数据库实例中所有key的数量:dbsize
查看当前数据库实例中所有的key:keys *
清空数据库实例:flushdb
清空所有的数据库实例:flushall
查看redis中的配置信息:config get * //查看所有的 //就是那个配置文件redis.conf
config get 字段 //查看指定的配置信息 //字段就是配置文件对应的字段
redis的5中数据结构
程序是用来处理数据的,Redis是用来存储数据的;程序处理完的数据要存储到redis中,不同特点的数据要存储在Redis中不同类型的数据结构中
数据结构
字符串: zhangsan 20 true string 单key:单value: username:zhangsan age:20
list列表: 13900009999 [email protected] 321321 list 单key:多有序value: contacts:13900009999,xxx,xxxx //顺序与放进去的顺序有关 有序
set集合: beijing shanghai chongqing tianjin set 单key:多无序value: city:bj sh cq tj
pojo: id:1001,name:zhangsan,age:20 hash 单key: 对象(属性:值): student:id:1001,name:zhangsan,age:20
zset 单key:多无序可排列vlaue: city:1000 tj,1200 cq,1500 sh,2000 bj //顺序与value值有关,可排列
(管理一个分数作为排列标准)
Redis的Key的操作命令
查看数据库中的可以:key key键匹配 //key键匹配可以搭配通配符使用 通配符:*任意数量的任意字符 ?任意1个字符 [ ] 匹配[]里边的1个字符
//例子 key a*b 、 key * key a? key a[zxy]判断key在数据库中是否存在:exists key键 [key键 key键 key键 ....] // 如果存在,则返回1;如果不存在,则返回0 //判断多个key是否存在, 返回值是存在的key的数量
移动指定key到指定的数据库实例:move key键 编号
查看指定key的剩余生存时间:ttl key键 //返回时间 //如果key没有设置生存时间,返回-1 如果key不存在,返回-2
设置key的最大生存时间:expire key键 秒数
查看指定key的数据类型:type key键 //就是返回什么5中数据结构
重命名key: rename key键 newkey键
删除指定的key:del key键 [key键 key键 .....] //返回值是实际删除的key的数量
string数据结构的操作命令 string:单key-单value
将string类型的数据设置到redis中:set 键 值 //若key键存在,会覆盖
从redis中获取string类型的数据:get 键
追加字符串:append 键 值 //返回追加之后的字符串长度 //若没有该key键,则相当于set命令
获取字符串数据的长度:strlen key键
将字符串数值进行加1运算:incr key键 //返回加1运算之后的数据 //若key键不存在,则set key键 0,再incr运算 要求key所表示value必须是数值,否则,报错
将字符串数值进行减1运算:decr key键 //返回减1运算之后的数据 //同上
将字符串数值进行加offset运算:incrby key键 偏移量 //返回加偏移量运算之后的数据 //同上
将字符串数值进行减offset运算:decrby key 偏移量 //返回减偏移量运算之后的数据 //同上
获取字符串key中从startIndex到endIndex的字符组成的子字符串:getrange key键 startIndex endIndex //下标从0开始,最后一个是长度-1,可以是负数
用value覆盖从下标为startIndex开始的字符串,能覆盖几个字符就覆盖几个字符:setrange key键 startIndex 替换值 //覆盖的长度以替换值为标准
设置字符串数据的同时,设置它最大生命周期:setex key键 秒数 值
设置string类型的数据value到redis数据库中,当key不存在时设置成功,否则,则放弃设置:setnx key value //若已有key则放弃命令
批量将string类型的数据设置到redis中:mset 键1 值1 键2 值2 .....
批量从redis中获取string类型的数据:mget 键1 键2 键3.....
批量设置string类型的数据value到redis数据库中,当所有key都不存在时设置成功,否则(只要有一个已经存在),则全部放弃设置:msetnx 键1 值1 键2 值2 .....
list数据结构的操作命令 list:单key-多有序的(可重复)value
多个value之间有顺序,最左侧是表头,最右侧是表尾,有下标从0开始,最后一个长度-1,可以为负数,下标由元素放入顺序决定
将一个或者多个值依次插入到列表的表头(左侧):lpush key键 值[值 值.....] //返回列表长度 //每次都放在表头作左,所以会把之前的放的往后挤
将一个或者多个值依次插入到列表的表尾(右侧):rpush key键 值[值 值.....]
获取指定列表中指定下标区间的元素:lrange key键 startIndex endIndex
从指定列表中移除并且返回表头元素:lpop key键
从指定列表中移除并且返回表尾元素:rpop key键
获取指定列表中指定下标的元素:lindex key键 index
获取指定列表的长度:llen key键
根据count值移除指定列表中跟value相等的数据:lrem key键 count数值 value count值>0:从列表的左侧移除count个数的跟value相等的数据;
count值<0:从列表的右侧移除count个数(去掉负号的count数值)的跟vlaue相等的数据;
count值=0:从列表中移除所有跟value相等的数据截取指定列表中指定下标区间的元素组成新的列表,并且赋值给key:ltrim key键 startIndex endIndex
将指定列表中指定下标的元素设置为指定值: lset key键 index 值
将value插入到指定列表中位于参考元素之前/之后的位置: linsert key before/after 参考元素 插入值
set数据结构的操作命令 set:单key-无序的(不可重复)value
通过key确定集合。取的时候,直接按照值取。
将一个或者多个元素添加到指定的集合中:sadd key键 值[值 值....] //如果值已有,则忽略该值 //返回成功加入的元素的个数
获取指定集合中所有的元素:smembers key键
判断指定元素在指定集合中是否存在:sismember key member //存在,返回1 不存在,返回0
获取指定集合的长度:scard key键
移除指定集合中一个或者多个元素:srem key键 值[值 值.....] //移除不存在的元素会被忽略 //返回成功成功移除的个数
随机获取指定集合中的一个或者多个元素:srandmember key键 [count] //count>0:随机获取的count个数,元素之间不能重复 //count<0: 随机获取的-count个,元素之间可以重复
从指定集合中随机移除一个或者多个元素:spop key键 [count]
将指定集合中的指定元素移动到另一个元素:smove 源key键 目标key键 移动的值
获取第一个集合中有、但是其它集合中都没有的元素组成的新集合:sdiff key键1 key键 [key键 key键 ....]
获取所有指定集合中都有的元素组成的新集合:sinter key键 key键 [key键 key键 ....]
获取所有指定集合中所有元素组成的大集合:sunion key键 key键 [key键 key键 .....]
hash数据结构的操作命令
hash:单key:field-value
field-value
……将一个或者多个field-vlaue对设置到哈希表中:hset key键 filed1 value1 [field2 value2 ....] //若field存在则覆盖value
获取指定哈希表中指定field的值:hget key键 field域
批量将多个field-value对设置到哈希表中: hmset key键 filed1 value1 [field2 value2 ....]
批量获取指定哈希表中的field的值:hmget key键 field1 [field2 field3 ....]
获取指定哈希表中所有的field和value:hgetall key键
从指定哈希表中删除一个或者多个field:hdel key键 field1 [field2 field3 ....]
获取指定哈希表中所有的filed个数:hlen key键
判断指定哈希表中是否存在某一个field:hexists key键 field域
获取指定哈希表中所有的field列表:hkeys key键
获取指定哈希表中所有的value列表:hvals key键
对指定哈希表中指定field值进行整数加法运算:hincrby key键 field域 整数
对指定哈希表中指定field值进行浮点数加法运算:hincrbyfloat key键 field域 小数
将一个field-vlaue对设置到哈希表中,当key-field已经存在时:hsetnx key键 field域 value值
zset数据结构的操作命令 zset:单key-多无序的(不可重复)可排列的(关联分数)value
本质是集合,元素不能重复。但是每个元素都关联一个分数,redis会根据分数进行排列(分数可重复),既然排列了就可以有下标
将一个或者多个member(元素)及其score(分数)值加入有序集合:zadd key键 score1 member1 [score2 member2 ....] //如果元素已经存在,则把分数覆盖
获取指定有序集合中指定下标区间的元素:zrange key键 startIndex endIndex [withscores] //withscores:不显示关联分数
获取指定有序集合中指定分数区间(闭区间)的元素:zrangebyscore key键 min分数 max分数 [withscores]
删除指定有序集合中一个或者多个元素:zrem key键 member1 [member2......]
获取指定有序集合中所有元素的个数:zcard key键
获取指定有序集合中分数在指定区间内的元素的个数:zcount key键 min分数 max分数
获取指定有序集合中指定元素的排名(排名从0开始): zrank key键 member元素
获取指定有序集合中指定元素的排名(按照分数从大到小的排名):zrevrank key键 member元素
获取指定有序集合中指定元素的分数:zscore key键 member元素
redis配置文件
redis安装完成之后,在redis的根沐会提供一个配置文件(redis.conf);redis服务可以参考配置文件中的参数进行运行;
只有启动redis服务器指定使用的配置文件,参数才会生效;否则,redis会采用默认的参数运行。redis配置信息:
一、redis配置文件中关于网络的配置:
port:配置redis服务运行的端口号;如果不配置port,则redis服务默认使用6379端口。
bind: redis服务被客户端连接时,客户端所能使用的ip地址。
默认情况下,不配置bind,客户端连接redis服务时,通过服务器上任何一个ip都能连接到redis服务;一旦配置了bind,客户端就只能通过bind指定的ip地址连接redis服务
一般情况下,bind都是配置服务器上某一个真实ip。
redis-cli :默认连接127.0.0.1本机上的6379端口服务
redis-cli -h 127.0.0.1 -p 6379:同上
redis-cli -h 192.168.11.128 -p 6379:*强调:一旦redis服务配置了port和bind(如果port不是6379、bind也不是127.0.0.1),客户端连接redis服务时,就要指定端口和ip:
redis-cli:默认连接127.0.0.1上的6379服务
redis-cli -h bind绑定的ip地址 -p port设置的端口:连接bind绑定的ip地址主机上的port设置的端口redis服务;
关闭redis服务时:redis-cli -h bind绑定的ip地址 -p port设置的端口 shutdowntcp-keepalive:连接保活策略
二、常规配置:
loglevel:配置日志级别。//开发阶段配置debug,上线阶段配置notice或者warning.
logfile:指定日志文件。redis在运行过程中,会输出一些日志信息;
默认情况下,这些日志信息会输出到控制台;我们可以使用logfile配置日志文件,使redis把日志信息输出到指定文件中。
databases:配置redis服务默认创建的数据库实例个数,默认值是16。三、安全配置:
requirepass:设置访问redis服务时所使用的密码;默认不使用。
此参数必须在protected-mode=yes时才起作用。
一旦设置了密码验证,客户端连接redis服务时,必须使用密码连接:redis-cli -h ip -p port -a 密码四、redis持久化配置
redis把数据存在内存中,redis提供持久化策略,在适当的时机采用适当手段把内存中的数据持久化到磁盘中,每次redis服务启动时,都可以把磁盘上的数据再次加载内存中使用。
RDB策略:在指定时间间隔内,redis服务执行指定次数的写操作,会自动触发一次持久化操作。
RDB策略是redis默认的持久化策略,redis服务开启时这种持久化策略就已经默认开启了。save 秒数 写操作次数:配置持久化策略
dbfilename:配置redis RDB持久化数据存储的文件 //默认是dump.rdb
dir: 配置redis RDB持久化文件所在目录
AOF策略:采用操作日志来记录进行每一次写操作,每次redis服务启动时,都会重新执行一遍操作日志中的指令。 //补充RDB策略最后一次操作可能触发不了的缺点
效率低下,redis默认不开启AOF功能。appendonly:配置是否开启AOF策略,yes表示开启,no表示关闭。默认是no。
appendfilename:配置操作日志文件一般情况,开启RDB足够了。
Redis事务
事务:把一组数据库命令放在一起执行,保证操作原子性,要么同时成功,要么同时失败。 //注意:redis没有事务回滚
Redis的事务:允许把一组redis命令放在一起,把命令进行序列化,然后一起执行,保证部分原子性。1)multi:用来标记一个事务的开始。
2)exec:用来执行事务队列中所有的命令。
3)redis的事务只能保证部分原子性:
a)如果一组命令中,有在压入事务队列过程中发生错误的命令,则本事务中所有的命令都不执行,能够保证事务的原子性。
b)如果一组命令中,在压入队列过程中正常,但是在执行事务队列命令时发生了错误,则只会影响发生错误的命令,不会影响其它命令的执行,不能够保证事务的原子性。4)discard:清除所有已经压入队列中的命令,并且结束整个事务。
5)watch:监控某一个键,当事务在执行过程中,此键代码的值发生变化,则本事务放弃执行;否则,正常执行。 watch key键
6)unwatch:放弃监控所有的键。 unwatch key键
redis消息的发布与订阅:redis客户端订阅频道,消息的发布者往频道上发布消息,所有订阅此频道的客户端都能够接受到消息。
1)subscribe:订阅一个或者多个频道的消息。 subscribe 频道1 频道2 频道3 ……
2)publish:将消息发布到指定频道 publish 频道 信息
3)psubcribe:订阅一个或者多个频道的消息,频道名支持通配符。 如:subscribe news.*
redis的主从复制:主少从多、主写从读、读写分离、主写同步复制到从。
搭建一主二从redis集群:
1)搭建三台redis服务:使用一个redis模拟三台redis服务------>提供三分redis配置文件:redis6379.conf、redis6380.conf、redis6381.conf
修改三份配置文件:以redis6379.conf为例
bind 127.0.0.1
port 6379
pidfile /var/run/redis_6379.pid
logfile "6379.log"
dbfilename dump6379.rdb
分别使用三个redis配置文件,启动三个redis服务:
redis-server redis6379.conf &
redis-server redis6380.conf &
redis-server redis6381.conf &
2)通过redis客户端分别连接三台redis服务:
redis-cli -h 127.0.0.1 -p 6379
redis-cli -h 127.0.0.1 -p 6380
redis-cli -h 127.0.0.1 -p 6381
3)查看三台redis服务在集群中的主从角色:
info replication
//默认情况下,所有的redis服务都是主机,即都能写和读,但是都还没有从机。 此时:三台rdis服务互相独立,互不影响。
4)设置主从关系:设从不设主
//在从机执行:slaveof 主机IP 主机端口
在6380上执行:slaveof 127.0.0.1 6379
在6381上执行:slaveof 127.0.0.1 6379全量复制:一旦主从关系确定,会自动把主库上已有的数据同步复制到从库。
增量复制:主库写数据会自动同步到从库。
主写从读,读写分离: 从库只能读不能写,主库既可读又可写,但一般不会操作主库读
若出现意外问题:
主机宕机:从机原地待命
关闭6379服务:redis-cli -h 127.0.0.1 -p 6379 shutdown //查看6380和6381服务的主从角色:info replication主机恢复:一切恢复正常
重启6379服务:redis-server redis6379.conf &
客户端连接6379:redis-cli -h 127.0.0.1 -p 6379从机宕机:主机少一个从机、其它从机不变
关闭6380服务: redis-cli -h 127.0.0.1 -p 6380 shutdown
查看6379服务的主从角色:info replication
查看6381服务的主从角色:info replication
从机恢复:需要重新设置主从关系
重启6380服务:redis-server redis6380.conf &
客户端连接6380:redis-cli -h 127.0.0.1 -p 6380
在6380上执行: slaveof 127.0.0.1 6379
5)从机上位:
a)主机宕机、从机原地待命:
关闭6379服务:redis-cli -h 127.0.0.1 -p 6379 shutdown
查看6380和6381服务的主从角色:info replication
b)从机断开原来主从关系:
在6380上执行:slaveof no one
查看6380服务的主从角色:info replication
c)重新设置主从关系:
在6381上执行:slaveof 127.0.0.1 6380
d)之前主机恢复、变成孤家寡人:
重启6379服务:redis-server redis6379.conf &
客户端连接6379:redis-cli -h 127.0.0.1 -p 6379
e)天堂变地狱:
在6379上执行:slaveof 127.0.0.1 6381
在6381上执行:info replication 既是主机又是从机 //只要有从机角色,都不能写数据
小结:一台主机配置多台从机,一台从机又可以配置多台从机,从而形成一个庞大的集群架构。
减轻一台主机的压力,但是增加了服务间的延迟时间。
redis哨兵模式:主机宕机、从机上位的自动版。
1)搭建一主二从集群架构:
2)提供哨兵配置文件:
在redis安装目下创建配置文件:redis_sentinel.conf
在文件里设置内容:sentinel monitor 自定义哨兵名 监控主机IP 监控主机端口号 哨兵的投票数 //哨兵投票数:哪一个从机最先达到规则,那个从机上位
3)启动哨兵服务:哨兵也占一个端口
redis-sentinel redis_sentinel.conf配置文件路径
4)主机宕机:哨兵程序自动选择从机上位。
关闭6379服务:redis-cli -h 127.0.0.1 -p 6379 shutdown
5)之前主机恢复:自动从属于新的主机。
重启6379服务:redis-server redis6379.conf &
客户端连接6379:redis-cli -h 127.0.0.1 -p 6379
java操作redis数据库:jedis是redis官方提供的操作redis数据的技术。
把所有的redis指令都定义成java工具类的方法,方法名和redis的指令名完全一样;
开发通过程序访问redis,只需要使用工具类及其方法即可。在java程序中访问redis:
1)创建maven版的java工程
2)添加jedis依赖
redis.clients
jedis
3.1.0
3)在Java程序中创建Jedis连接
Jedis jedis = new Jedis(IP字符串,端口号数值) //注意关闭linux的防火墙
使用Jedis实例操作redis服务
jedis.命令(参数) //方法名与指令同名//事务特殊:
jedis.multi();返回一个事务对象,操作事务对象来进行事务
事务对象.命令(参数)