'); } '); } Redis简介 | Journey to paradise

Redis简介


Redis简介

​ Redis是一个用C语言编写的、开源的、基于内存运行并支持持久化的、高性能的NoSQL数据库,也是当前热门的NoSQL数据库之一。

​ Redis中的数据以K-V模型存储数据,大部分时间都是存储内存中的,适合存储频繁访问、数据量比较小的数据,常用作缓存数据库。

  • 关系型数据库:oracle、mysql、DB2、sqlserver、….

    • 数据模型:表
  • 非关系型数据库(NoSql): 彻底改变底层存储机制。不再采用关系数据模型,而是采用聚合数据结构存储数据: redis、mongoDB、HBase、….

    • 数据模型: 聚合模型—把一组相关联的数据作为一个整体进行存储和管理。

      • BSON:数据保存到键值对中、数据和数据之间用逗号隔开,{}表示对象,[]表示数组。

        • eg:

          {
           "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"
               	}
              ]
            }
          }
          
      • K-V键值对、列簇、图表模型等。Redis采用的是K-V模型存储数据。

redis的特点

  • 支持数据持久化:Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用

  • 支持多种数据结构:Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储

  • 支持数据备份:Redis支持数据的备份,即master-slave模式的数据备份

Redis中的操作命令

redis服务的启动与关闭

  • ​ 启动redis服务
    • 前台启动:在任何目录下执行 redis-server
    • 后台启动:在任何目录下执行 redis-server &
    • 启动redis服务时,指定配置文件:redis-server reids.conf &
  • ​ 关闭redis服务
    • 通过kill命令
      • ps-ef|grep redis 查看pid
      • kill -9 pid
    • 通过redis-cli命令关闭
      • redis-cli shutdown
  • 启动redis客户端(用来连接redis服务,向redis服务端发送命令,并且显示redis服务处理结果。)
    • redis-cli:启动redis自带的客户端,默认连接127.0.0.1(本机)的6379端口上的redis服务)
    • redis-cli -p 端口号:连接127.0.0.1(本机)的指定端口上的redis服务
    • redis-cli -h ip地址 -p 端口:连接指定ip主机上的指定端口的redis服务
  • 退出客户端
    • 在客户端执行命令:exit或者quit

redis的基本知识

  • 测试redis服务的性能:redis-benchmark
  • 查看redis服务是否正常运行:ping (如果正常返回-pong)
  • 查看redis服务器的统计信息
    • info: 查看redis服务的所有统计信息
    • info [信息段]: 查看redis服务器的指定的统计信息
      • eg:info replication: 查看本端口的从属关系
  • redis的数据库实例
    • 作用类似于mysql的数据库实例,redis中的数据库实例只能由redis服务来创建和维护,开发人员不能修改和自行创建数据库实例
    • 默认情况下,redis会自动创建16个数据库实例,并且给这些数据库实例进行编号,从0开始,一直到15,使用时通过编号来使用数据库
    • 可以通过配置文件,指定redis自动创建的数据库个数
    • redis的每一个数据库实例本身占用的存储空间是很少的,所以也不造成存储空间的太多浪费
    • 默认情况下,redis客户端连接的是编号是0的数据库实例;可以使用select index切换数据库实例
    • 对数据库实例的常用操作命令
      • dbsize:查看当前数据库实例中所有key的数量
      • keys *:查看当前数据库实例中所有的key
      • flushdb:清空当前数据库实例
      • flushall:清空所有的数据库实例
      • config get *:查看redis中所有的配置信息
      • config get parameter: 查看redis中的指定的配置信息

Redis的五种数据结构

​ 程序处理完的数据要存储到redis中,不同特点的数据要存储在Redis中不同类型的数据结构中。

  • 字符串string——单key:单value
    • eg:username:zhangsan
  • 列表list——单key:多有序value
    • 多个value之间有顺序,最左侧是表头,最右侧是表尾
    • 每一个元素都有下标,表头元素的下标是0,依次往后排序,最后一个元素下标是列表长度-1
    • 每一个元素的下标又可以用负数表示,负下标表示从表尾计算,最后一个元素下标用-1表示
    • 元素在列表中的顺序或者下标由放入的顺序来决定
    • 通过key和下标来操作数据
    • eg:contacts:13900009999,xxx,xxxx
  • 集合set——单key:多无序value
    • 一个key对应多个vlaue, value之间没有顺序,并且不能重复
    • 通过业务数据直接操作集合
    • eg:city:bj sh cq tj
  • hash——单key: 对象(属性:值)
    • eg:student:id:1001,name:zhangsan,age:20
  • zset——单key:多有序vlaue
    • 有序集合, 本质上是集合,所有元素不能重复
    • 每一个元素都关联一个分数,redis会根据分数对元素进行自动排序,分数可以重复
    • 既然有序集合中每一个元素都有顺序,那么也都有下标
    • 有序集合中元素的排序规则和列表中元素的排序规则不一样
    • eg:city:1000 tj,1200 cq,1500 sh,2000 bj

Redis中对数据的操作命令

redis中有关key的操作命令
  • 查看数据库中的key:keys pattern
    • *:匹配0个或者多个字符
      • keys *:查看数据库中所有的key
      • keys k*:查看数据库中所有以k开头的key
      • keys h*o:查看数据库中所有以h开头、以o结尾的key
    • ?: 匹配1个字符
      • keys h?o: 查看数据库中所有以h开头、以o结尾的、并且中间只有一个字符的key
    • []:匹配[]里边的1个字符
      • keys h[abc]llo:查看数据库中所有以h开头以llo结尾,并且h后边只能取abc中的一个字符的key
  • 判断key在数据库中是否存在:exists key
    • 如果存在,则返回1;如果不存在,则返回0
    • exists key [key key ….] 返回值是存在的key的数量
  • 移动指定key到指定的数据库实例:move key index
  • 查看指定key的剩余生存时间:ttl key
    • 如果key没有设置生存时间,返回-1
    • 如果key不存在,返回-2
  • 设置key的最大生存时间:expire key seconds
    • expire k2 20
  • 查看指定key的数据类型:type key
    • type k1
  • 重命名key: rename key newkey
    • rename hello k2
  • 删除指定的key:del key [key key …..]
    • 返回值是实际删除的key的数量
redis中有关string类型数据的操作命令
  • 将string类型的数据设置到redis中:set 键 值
    • 如果key已经存在,则后来的value会把以前的value覆盖掉
      • set zsname zhangsan
  • 从redis中获取string类型的数据:get 键
  • 追加字符串:append key value
    • 返回追加之后的字符串长度
    • 如果key不存在,则新创建一个key,并且把value值设置为value。
      • set phone 1389999 append phone 8888 get “phone”——“13899998888”
  • 获取字符串数据的长度:strlen key
  • 将字符串数值进行加1运算:incr key
    • 返回加1运算之后的数据
    • 如果key不存在,首先设置一个key,值初始化为0,然后进行incr运算。
    • 要求key所表示value必须是数值,否则,报错
  • 将字符串数值进行减1运算:decr key
    • 返回减1运算之后的数据
    • 如果key不存在,首先设置一个key,值初始化为0,然后进行decr运算。
    • 要求key所表示value必须是数值,否则,报错
  • 将字符串数值进行加offset运算:incrby key offset
    • 返回加offset运算之后的数据
    • 如果key不存在,首先设置一个key,值初始化为0,然后进行incrby运算。
    • 要求key所表示value必须是数值,否则,报错
  • 将字符串数值进行减offset运算:decrby key offset
    • 返回减offset运算之后的数据
    • 如果key不存在,首先设置一个key,值初始化为0,然后进行decrby运算。
    • 要求key所表示value必须是数值,否则,报错
  • 闭区间获取字符串key中从startIndex到endIndex的字符组成的子字符串:getrange key startIndex endIndex
    • 下标自左至右,从0开始,依次往后,最后一个字符的下标是字符串长度-1;
  • 用value覆盖从下标为startIndex开始的字符串,能覆盖几个字符就覆盖几个字符:setrange key startIndex value
  • 设置字符串数据的同时,设置它最大生命周期:setex key seconds value
  • 设置string类型的数据value到redis数据库中,当key不存在时设置成功,否则,则放弃设置:setnx key value
  • 批量将string类型的数据设置到redis中:mset 键1 值1 键2 值2 …..
  • 批量从redis中获取string类型的数据:mget 键1 键2 键3…..
  • 批量设置string类型的数据value到redis数据库中,当所有key都不存在时设置成功,否则(只要有一个已经存在),则全部放弃设置:msetnx 键1 值1 键2 值2 …..
redis中有关list类型数据的操作命令
  • 将一个或者多个值依次插入到列表的表头(左侧):lpush key value [value value …..]
  • 获取指定列表中指定下标区间的元素:lrange key startIndex endIndex
  • 将一个或者多个值依次插入到列表的表尾(右侧):rpush key value [value value …..]
  • 从指定列表中移除并且返回表头元素:lpop key
  • 从指定列表中移除并且返回表尾元素:rpop key
  • 获取指定列表中指定下标的元素:lindex key index
  • 获取指定列表的长度:llen key
  • 根据count值移除指定列表中跟value相等的数据:lrem key count value
    • count>0:从列表的左侧移除count个跟value相等的数据
    • count<0:从列表的右侧移除count个跟vlaue相等的数据
    • count=0:从列表中移除所有跟value相等的数据
  • 截取指定列表中指定下标区间的元素组成新的列表,并且赋值给key:ltrim key startIndex endIndex
    • lpush list04 1 2 3 4 5 ltrim list04 1 3 结果:5 4 3 2 1
  • 将指定列表中指定下标的元素设置为指定值: lset key index value
  • 将value插入到指定列表中位于pivot元素之前/之后的位置: linsert key before/after pivot vlaue
redis中有关set类型数据的操作命令
  • 将一个或者多个元素添加到指定的集合中:sadd key value [value value ….]
    • 如果元素已经存在,则会忽略
    • 返回成功加入的元素的个数
  • 获取指定集合中所有的元素:smembers key
  • 判断指定元素在指定集合中是否存在:sismember key member
    • 存在,返回1
    • 不存在,返回0
  • 获取指定集合的长度:scard key
  • 移除指定集合中一个或者多个元素:srem key member [member …..]
    • 不存在的元素会被忽略
    • 返回成功成功移除的个数
  • 随机获取指定集合中的一个或者多个元素:srandmember key [count]
    • count>0:随机获取的多个元素之间不能重复
    • count<0: 随机获取的多个元素之间可能重复
  • 从指定集合中随机移除一个或者多个元素:spop key [count]
  • 将指定集合中的指定元素移动到另一个元素:smove source dest member
  • 获取第一个集合中有、但是其它集合中都没有的元素组成的新集合:sdiff key key [key key ….]
  • 获取所有指定集合中都有的元素组成的新集合:sinter key key [key key ….]
  • 获取所有指定集合中所有元素组成的大集合:sunion key key [key key …..]
redis中有关hash类型的操作命令
  • 将一个或者多个field-vlaue对设置到哈希表中:hset key filed1 value1 [field2 value2 ….]
    • 如果key 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
  • 获取指定哈希表中所有的value列表:hvals key
  • 对指定哈希表中指定field值进行整数加法运算:hincrby key field int
  • 对指定哈希表中指定field值进行浮点数加法运算:hincrbyfloat key field float
  • 将一个field-vlaue对设置到哈希表中,当key-field已经存在时,则放弃设置;否则,设置file-value:hsetnx key field value
redis中有关zset类型数据的操作命令
  • 将一个或者多个member及其score值加入有序集合:zadd key score member [score member ….]
    • 如果元素已经存在,则把分数覆盖
  • 获取指定有序集合中指定下标区间的元素:zrange key startIndex endIndex [withscores]
  • 获取指定有序集合中指定分数区间(闭区间)的元素:zrangebyscore key min max [withscores]
  • 删除指定有序集合中一个或者多个元素:zrem key member [member……]
  • 获取指定有序集合中所有元素的个数:zcard key
  • 获取指定有序集合中分数在指定区间内的元素的个数:zcount key min max
  • 获取指定有序集合中指定元素的排名(排名从0开始): zrank key member
  • 获取指定有序集合中指定元素的分数:zscore key member
  • 获取指定有序集合中指定元素的排名(按照分数从大到小的排名):zrevrank key member

redis的配置文件

​ redis安装完成之后,在redis的根目录会提供一个配置文件(redis.conf);redis服务可以参考配置文件中的参数进行运行;只有启动redis服务器指定使用的配置文件,参数才会生效;否则,redis会采用默认的参数运行

网络配置
  • port:配置redis服务运行的端口号
    • 如果不配置port,则redis服务默认使用6379端口
      • redis-cli :默认连接127.0.0.1本机上的6379端口服务
    • 强调:一旦redis服务配置了port和bind(如果port不是6379、bind也不是127.0.0.1),客户端连接redis服务时,就要指定端口和ip
      • redis-cli -h bind绑定的ip地址 -p port设置的端口:连接bind绑定的ip地址主机上的port设置的端口redis服务
      • redis-cli -h bind绑定的ip地址 -p port设置的端口 shutdown:关闭redis服务
  • bind: redis服务被客户端连接时,客户端所能使用的ip地址
    • 默认情况下,不配置bind,客户端连接redis服务时,通过服务器上任何一个ip都能连接到redis服务
    • 一旦配置了bind,客户端就只能通过bind指定的ip地址连接redis服务
    • 一般情况下,bind都是配置服务器上某一个真实ip
  • tcp-keepalive:连接保活策略
    • 如果两端的 TCP 连接一直没有数据交互,达到了触发 TCP 保活机制的条件,那么内核里的 TCP 协议栈就会发送探测报文。
      • 如果对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 对端会正常响应,这样 TCP 保活时间会被重置,等待下一个 TCP 保活时间的到来
      • 如果对端主机崩溃,或对端由于其他原因导致报文不可达。当 TCP 保活的探测报文发送给对端后,没有响应,连续几次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡
常规配置
  • loglevel:配置日志级别,开发阶段配置debug,上线阶段配置notice或者warning
  • logfile:指定日志文件。redis在运行过程中,会输出一些日志信息
    • 默认情况下,这些日志信息会输出到控制台
    • 使用logfile配置日志文件,使redis把日志信息输出到指定文件中
安全配置
  • requirepass:设置访问redis服务时所使用的密码
    • 默认不使用
    • 此参数必须在protected-mode=yes时才起作用
    • 一旦设置了密码验证,客户端连接redis服务时,必须使用密码连接:redis-cli -h ip -p port -a pwd

redis的持久化

​ redis提供持久化策略,在适当的时机采用适当手段把内存中的数据持久化到磁盘中,每次redis服务启动时,都可以把磁盘上的数据再次加载内存中使用。

  • RDB策略

    • 在指定时间间隔内,redis服务执行指定次数的写操作,会自动触发一次持久化操作,将内存中的数据写入到磁盘中
    • RDB策略是redis默认的持久化策略,redis服务开启时这种持久化策略就已经默认开启了。
    • 配置
      • save :配置持久化策略
      • dbfilename:配置redis RDB持久化数据存储的文件
      • dir: 配置redis RDB持久化文件所在目录
  • AOF策略

    • 采用操作日志来记录进行每一次写操作,每次redis服务启动时,都会重新执行一遍操作日志中的指令。
    • 效率低下,redis默认不开启AOF功能
    • 配置
      • appendonly:配置是否开启AOF策略
      • appendfilename:配置操作日志文件

​ 根据数据的特点决定开启哪种持久化策略, 一般情况,开启RDB足够了。

reids的事务

​ 事务:把一组数据库命令放在一起执行,保证操作原子性,要么同时成功,要么同时失败。
​ Redis的事务:允许把一组redis命令放在一起,把命令进行序列化,然后一起执行,保证部分原子性。

redis事务常用命令:

  • 开启事务:multi

    • 事务开启后,redis会将后续的命令逐个放入队列中
    • 开启成功返回OK
    • image-20220624202435900
  • 执行事务中的命令:exec

    • 在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态

    • 如果在把命令压入队列的过程中报错,则整个队列中的命令都不会执行,执行结果报错

    • 如果在压队列的过程中正常,在执行队列中某一个命令报错,则只会影响本条命令的执行结果,其它命令正常运行

    • 当使用WATCH命令时,只有当受监控的键没有被修改时,EXEC命令才会执行事务中的命令;而一旦执行了exec命令,之前加的所有watch监控全部取消

    • 命令时,如果事务执行中止,那么EXEC命令就会返回一个Null值

  • 清除事务中的命令:discard

    • 清除所有先前在一个事务中放入队列的命令,并且结束事务
    • 如果使用了watch命令,那么discard命令就会将当前连接监控的所有键取消监控
  • 监控事务:watch

    • 监控某一个键,当事务在执行过程中,此键代码的值发生变化,则本事务放弃执行;否则,正常执行
    • Watch命令相当于关系型数据库中的乐观锁
  • 清除事务监控:unwatch

    • 清除所有先前为一个事务监控的键
    • 如果在watch命令之后调用了exec或d命discard令,那么就不需要手动调用unwatch命令

​ 单独的隔离操作:事务中的所有命令都会序列化、顺序地执行。事务在执行过程中,不会被其它客户端发来的命令请求所打断,除非使用watch命令监控某些键。

​ 不保证事务的原子性:redis同一个事务中如果一条命令执行失败,其后的命令仍然可能会被执行,redis的事务没有回滚。Redis已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为Redis不需要事务回滚的能力。

redis消息的订阅与发布

​ redis客户端订阅频道,消息的发布者往频道上发布消息,所有订阅此频道的客户端都能够接受到消息。

​ 相关命令:

  • subscrib:订阅一个或者多个频道的小溪
    • eg:subscribe ch1 ch2 ch3
  • publish:将消息发布到指定频道
    • eg:publish ch1 hello
  • psubcribe:订阅一个或者多个频道的消息,频道名支持通配符
    • eg:psubscribe news.*

消息的订阅与发布有更优秀的中间件来执行(activeMQ2….)

redis的主从复制

​ 主少从多、主写从读、读写分离、主写同步复制到从。

​ 相关命令:

  • 查看当前redis服务在集群中的主从角色:info replication

    • 默认情况下,所有的redis服务都是主机,即都能写和读,但是都还没有从机
  • 设置主从关系:slaveof 主机ip 端口号

    • 将当前主机设为主机ip 端口号的从机
    • 设从不设主
  • 全量复制:一旦主从关系确定,会自动把主库上已有的数据同步复制到从库

  • 增量复制:主库写数据会自动同步到从库

  • 主写从读,读写分离

    • 主机宕机、从机原地待命
    • 主机恢复、一切恢复正常
    • 从机宕机、主机少一个从机、其它从机不变
    • 从机恢复、从机为主机,需要重新设置主从关系
  • 从机上位

    • 主机宕机、从机原地待命
    • 从机断开原来主从关系:slaveof no one
    • 重新设置主从关系:slaveof 主机ip 主机port
    • 既是主机又是从机的只能读不能写

​ 一台主机配置多台从机,一台从机又可以配置多台从机,从而形成一个庞大的集群架构。减轻一台主机的压力,但是增加了服务间的延迟时间。

redis的哨兵模式

​ 主机宕机、从机上位的自动版。Redis提供了哨兵的命令,哨兵命令是一个独立的进程,哨兵通过发送命令,来监控主从服务器的运行状态,如果检测到master故障了根据投票数自动将某一个slave转换master,然后通过消息订阅模式通知其它slave,让它们切换主机。然而,一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多哨兵进行监控。

相关命令:

  • 创建哨兵文件sentinel.conf
  • 启动哨兵:redis-sentinel 哨兵文件全路径
  • 开启监控:sentinel monitor dc-redis 指定监控主机的ip地址 port端口 得到哨兵的投票数
    • 当哨兵投票数大于或者等于此数时切换主从关系
  • 设置密码:sentinel auth-pass mymaster pwd

哨兵模式三大任务:监控,提醒,自动故障迁移。

Jedis操作Redis

​ jedis是redis官方提供的在java应用中操作redis数据的技术。 把所有的redis指令都定义成java工具类的方法,方法名和redis的指令名完全一样。

​ 开发通过程序访问redis,只需要使用工具类及其方法即可。

在java程序中访问redis:

  1. 创建maven版的java工程

  2. 添加jedis依赖

    <dependency>                   	      		
        <groupId>redis.clients</groupId>        
        <artifactId>jedis</artifactId>
          <version>3.3.0</version>
    </dependency>
    

​ 3.创建Jedis连接(关闭linux的防火墙)

//连接jedis
Jedis jedis=new Jedis("主机ip",主机port);

​ 4.使用Jedis类中的方法操作redis

//连接redis
Jedis jedis=new Jedis("192.168.148.132",6380);
//使用jedis对象
String res= jedis.ping();
System.out.println(res);

Set<String> keys = jedis.keys("*");
for (String key:keys)&#123;
    System.out.println(key);
&#125;

Boolean k2 = jedis.exists("k2");
System.out.println(k2);

Long k21 = jedis.move("k2", 1);
System.out.println(k21);

jedis.select(1);
//.......

遇到的问题及解决方法:

问题1: java.net.SocketTimeoutException: connect timed out

解决方法:

 1. 关闭服务器防火墙:systemctl stop firewalld
 2. 重启redis服务(可能之前改了配置没有重启服务,还存有缓存,导致客户端向服务器发送接口的时候没有得到响应)
  - 导致有缓存的原因:
    -  防火墙放开端口
    - 后台更改了ip配置等等

Redis安装

  1. 官网下载redis到window上

  2. 使用Xftp上传redis-5.0.2.tar.gz到Linux系统

  3. 执行linux命令tar -zxvf redis-5.0.2.tar.gz -C /opt 解压redis-5.0.2.tar.gz到/opt目录

  4. 联网情况下执行命令yum -y install gcc安装编译器gcc

    • 编译结果:在redis的安装目录下src目录中,生成redis的一系列可执行文件。
  5. cd进入解压目录,执行命令make编译redis

    • 编译结果:在redis的安装目录下src目录中,生成redis的一系列可执行文件。
  6. 执行命令make install 把redis的安装目录下src目录中生成redis的一系列可执行文件拷贝到/usr/local/bin中,在任何目录下都可以执行redis命令。


文章作者: 涂爽
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 涂爽 !
评论
 上一篇
CRM项目SSM框架构建(一) CRM项目SSM框架构建(一)
CRM项目简介​ Customer Relationship Management 客户关系管理系统,企业级应用,传统应用;给销售或者贸易型公司使用,在市场,销售,服务等各个环节中维护客户关系。 CRM项目的宗旨:增加新客户,留住老客户,把
2022-06-22
下一篇 
linux常用命令 linux常用命令
文件和目录操作 文件查看和处理 打包和解压 PRM包管理命令 YUM包管理命令 DPKG包管理命令 关机/重启/注销 APT软件工具 常见系统服务命令 系统信息和性能查看 磁盘和分区 用户和用户组 网络和进程管理 常见
2022-06-19
  目录