简介

export LANG=zh_CN.gbk
192.168.**.128
systemctl stop firewalld.service
为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,就是NoSql。它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。

Redis是使用c语言开发的一个高性能键值数据库。Redis可以通过一些键值类型来存储数据。

键值类型:
  1. String字符类型
  2. hash散列类型
  3. list列表类型
  4. set集合类型
  5. sortedset有序集合类型
应用场景
  1. 缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
  2. 分布式集群架构中的session分离。
  3. 聊天室的在线好友列表。
  4. 任务队列。(秒杀、抢购、12306等等)
  5. 应用排行榜。
  6. 网站访问统计。
  7. 数据过期处理(可以精确到毫秒)

安装

  1. 解压缩: #tar -zxf redis-3.0.0.tar.gz
  2. 安装c语言环境:#yum install gcc-c++
  3. 编译redis源码:

    cd redis-3.0.0

    make

  4. 安装redis:#make install PREFIX=/usr/local/redis
  5. 前端启动redis,在bin目录下:# ./redis-server
    强制关闭:Ctrl+c,一旦客户端关闭,则redis服务也停掉。
  6. 后端启动redis,
    将redis解压之后的源码包中的redis.conf文件拷贝到bin目录下:[root@andy bin]# cp /root/redis-3.0.0/redis.conf ./
    修改redis.conf 中daemonize no 为daemonize yes: vi redis.conf
    启动redis: ./redis-server redis.conf
    查看是否启动成功:ps -aux | grep redis
    关闭redis:[root@andy bin]# ./redis-cli shutdown

数据类型

  1. string

    赋值:SET key value
    取值:GET key
    取值并赋值:GETSET key value
    设置/获取多个键值
    MSET key value key value …
    MGET key key …
    删除:DEL key
    递增数字:INCR key
    增加指定的整数:INCRBY key increment
    递减数值:DECR key
    减少指定的整数:DECRBY key decrement
    其它命令...
    向尾部追加值 :APPEND key value
    取字符串长度:STRLEN key ,如果不存在则长度为0

  2. hash散列类型

    赋值,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。
    设置一个字段值:HSET key field value hset user username zhangsan
    设置多个字段值:HMSET key field value [field value ...]
    当字段不存在时赋值,如果字段存在时不执行任何操作:HSETNX key field value

    获取一个字段值:HGET key field
    获取多个字段值:HMGET key field [field ...]
    获取所有字段值:HGETALL key

    删除一个或多个字段 :HDEL key field [field ...]

    增加数字:HINCRBY key field increment
    hincrby user age 2 将用户的年龄加2

    其它命令
    判断字段是否存在:HEXISTS key field
    只获取字段名或字段值:HKEYS key 、 HVALS key
    获取字段数量 :HLEN key

  3. list

    Redis的list是采用来链表来存储的
    左边增加元素 :LPUSH key value [value ...]
    右边增加元素 :RPUSH key value [value ...]
    查看列表: LRANGE key start stop
    索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
    从列表两端弹出元素 :LPOP key、RPOP key
    获取列表中元素的个数:LLEN key

    其它命令(自学)
    删除列表中指定的值 :LREM key count value
    LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
    当count>0时, LREM会从列表左边开始删除。
    当count<0时, LREM会从列表后边开始删除。
    当count=0时, LREM删除所有值为value的元素。

    获得指定索引的元素值:LINDEX key index
    设置指定索引的元素值:LSET key index value
    只保留列表指定片段:LTRIM key start stop
    向列表中插入元素:LINSERT key BEFORE|AFTER pivot value
    该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
    将元素从一个列表转移到另一个列表中 :RPOPLPUSH source destination

  4. set

    增加元素 :SADD key member [member ...]
    删除元素: SREM key member [member ...]
    获得集合中的所有元素 :SMEMBERS key
    判断元素是否在集合中:SISMEMBER key member
    运算命令
    集合的差集运算 A-B:SDIFF key [key ...]
    集合的交集运算 A ∩ B:SINTER key [key ...]
    集合的并集运算 A ∪ B:SUNION key [key ...]

    其它命令(自学)
    获得集合中元素的个数:SCARD key
    从集合中弹出一个元素: SPOP key
    注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出

  5. sortedset

    Sortedset是有序集合,可排序的,但是唯一。

    Sortedset和set的不同之处,是会给set中的元素添加一个分数,然后通过这个分数进行排序。

    增加元素: ZADD key score member [score member ...]
    获取元素的分数:ZSCORE key member
    删除元素: ZREM key member [member ...]
    移除有序集key中的一个或多个成员,不存在的成员将被忽略。
    当key存在但不是有序集类型时,返回一个错误。

    获得排名在某个范围的元素列表 :
    ZRANGE key start stop [WITHSCORES]:按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
    ZREVRANGE key start stop [WITHSCORES]:按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
    如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数

    127.0.0.1:6379> zrange scoreboard 0 1 WITHSCORES
    1) "zhangsan"
    2) "80"
    3) "wangwu"
    4) "94"

    获取元素的排名:
    ZRANK key member:从小到大
    ZREVRANK key member:从大到小

    其它命令(自学)
    获得指定分数范围的元素 :ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

    127.0.0.1:6379> ZRANGEBYSCORE scoreboard 90 97 WITHSCORES
    1) "wangwu"
    2) "94"
    3) "lisi"
    4) "97"
    127.0.0.1:6379> ZRANGEBYSCORE scoreboard 70 100 limit 1 2
    1) "wangwu"
    2) "lisi"

    增加某个元素的分数:ZINCRBY key increment member
    返回值是更改后的分数

    127.0.0.1:6379> ZINCRBY scoreboard 4 lisi 
    "101“

    获得集合中元素的数量:ZCARD key

    127.0.0.1:6379> ZCARD scoreboard
    (integer) 3

    获得指定分数范围内的元素个数:ZCOUNT key min max

    127.0.0.1:6379> ZCOUNT scoreboard 80 90
    (integer) 1

    按照排名范围删除元素:ZREMRANGEBYRANK key start stop

    127.0.0.1:6379> ZREMRANGEBYRANK scoreboard 0 1
    (integer) 2 
    127.0.0.1:6379> ZRANGE scoreboard 0 -1
    1) "lisi"

    按照分数范围删除元素:ZREMRANGEBYSCORE key min max

    127.0.0.1:6379> zadd scoreboard 84 zhangsan   
    (integer) 1
    127.0.0.1:6379> ZREMRANGEBYSCORE scoreboard 80 100
    (integer) 1

集群

安装ruby

集群管理工具(redis-trib.rb)是使用ruby脚本语言编写的。

  1. 安装ruby

    [root@andy bin2]# yum install ruby
    [root@andy bin2]# yum install rubygems 
  2. 将redis安装包上传到linux系统
    redis-3.0.0.gem
  3. 安装ruby和redis接口

    [root@andy ~]# gem install redis-3.0.0.gem 
  4. 将redis-3.0.0包下src目录中的 redis-trib.rb 拷贝到redis19/redis-cluster/

    [root@andy src]# cd /usr/local/redis19/
    [root@andy redis19]# mkdir redis-cluster
    [root@andy redis19]# cd /root/redis-3.0.0/src/
    [root@andy src]# cp redis-trib.rb  /usr/local/redis19/redis-cluster
搭建集群

搭建集群最少也得需要3台主机,如果每台主机再配置一台从机的话,则最少需要6台机器。
端口设计如下:7001-7006

  1. 复制出一个7001机器
    [root@andy redis19]# cp bin ./redis-cluster/7001 –r
  2. 如果存在持久化文件,则删除
    [root@andy 7001]# rm -rf appendonly.aof dump.rdb
  3. 设置集群参数
    cluster-enabled yes
  4. 修改端口
    port 7001
  5. 复制出7002-7006机器
  6. 修改7002-7006机器的端口
  7. 启动7001-7006这六台机器
    创建启动文件,start-all.sh

    cd 7001
    ./redis-server redis.conf
    cd ..
    cd 7002
    ./redis-server redis.conf
    cd ..
    cd 7003
    ./redis-server redis.conf
    cd ..
    cd 7004
    ./redis-server redis.conf
    cd ..
    cd 7005
    ./redis-server redis.conf
    cd ..
    cd 7006
    ./redis-server redis.conf
    cd ..

    创建关闭文件,shutdown-all.sh

    cd 7001
    ./redis-cli -p 7001 shutdown
    cd ..
    cd 7002
    ./redis-cli -p 7002 shutdown
    cd ..
    cd 7003
    ./redis-cli -p 7003 shutdown
    cd ..
    cd 7004
    ./redis-cli -p 7004 shutdown
    cd ..
    cd 7005
    ./redis-cli -p 7005 shutdown
    cd ..
    cd 7006
    ./redis-cli -p 7006 shutdown
    cd ..
  8. 修改start-all.sh文件的权限

    [root@andy redis-cluster]# chmod u+x start-all.sh
    [root@andy redis-cluster]# ./start-all.sh
  9. 创建集群

    [root@andy redis-cluster]# ./redis-trib.rb create --replicas 1 192.168.242.137:7001 192.168.242.137:7002 192.168.242.137:7003 192.168.242.137:7004 192.168.242.137:7005  192.168.242.137:7006

    连接集群:

    [root@andy 7001]# ./redis-cli -h 192.168.242.137 -p 7001 –c 

    -c:指定是集群连接
    查看集群信息:192.168.242.137:7002> cluster info
    查看集群节点:192.168.242.137:7002> cluster nodes

    代码:

    @Test
    public void jedisCluster(){
        Set<HostAndPort> nodes = new HashSet<>();
        nodes.add(new HostAndPort("192.168.93.128",7001));
        nodes.add(new HostAndPort("192.168.93.128",7002));
        nodes.add(new HostAndPort("192.168.93.128",7003));
        nodes.add(new HostAndPort("192.168.93.128",7004));
        nodes.add(new HostAndPort("192.168.93.128",7005));
        nodes.add(new HostAndPort("192.168.93.128",7006));
        JedisCluster cluster = new JedisCluster(nodes);
        cluster.set("s4","4444");
        String s4 = cluster.get("s4");
        System.out.println(s4);
        cluster.close();
    }

    使用spring

    <!-- 连接池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
       <!-- 最大连接数 -->
       <property name="maxTotal" value="30" />
       <!-- 最大空闲连接数 -->
       <property name="maxIdle" value="10" />
       <!-- 每次释放连接的最大数目 -->
       <property name="numTestsPerEvictionRun" value="1024" />
       <!-- 释放连接的扫描间隔(毫秒) -->
       <property name="timeBetweenEvictionRunsMillis" value="30000" />
       <!-- 连接最小空闲时间 -->
       <property name="minEvictableIdleTimeMillis" value="1800000" />
       <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
       <property name="softMinEvictableIdleTimeMillis" value="10000" />
       <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
       <property name="maxWaitMillis" value="1500" />
       <!-- 在获取连接的时候检查有效性, 默认false -->
       <property name="testOnBorrow" value="true" />
       <!-- 在空闲时检查有效性, 默认false -->
       <property name="testWhileIdle" value="true" />
       <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
       <property name="blockWhenExhausted" value="false" />
    </bean>
    <!-- redis集群 -->
    <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
       <constructor-arg index="0">
         <set>
            <bean class="redis.clients.jedis.HostAndPort">
               <constructor-arg index="0" value="192.168.101.3"></constructor-arg>
               <constructor-arg index="1" value="7001"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
               <constructor-arg index="0" value="192.168.101.3"></constructor-arg>
               <constructor-arg index="1" value="7002"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
               <constructor-arg index="0" value="192.168.101.3"></constructor-arg>
               <constructor-arg index="1" value="7003"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
               <constructor-arg index="0" value="192.168.101.3"></constructor-arg>
               <constructor-arg index="1" value="7004"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
               <constructor-arg index="0" value="192.168.101.3"></constructor-arg>
               <constructor-arg index="1" value="7005"></constructor-arg>
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
               <constructor-arg index="0" value="192.168.101.3"></constructor-arg>
               <constructor-arg index="1" value="7006"></constructor-arg>
            </bean>
         </set>
       </constructor-arg>
       <constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg>
    </bean>

    测试代码

    private ApplicationContext applicationContext;
       @Before
       public void init() {
         applicationContext = new ClassPathXmlApplicationContext(
               "classpath:applicationContext.xml");
       }
    
       // redis集群
       @Test
       public void testJedisCluster() {
         JedisCluster jedisCluster = (JedisCluster) applicationContext
               .getBean("jedisCluster");
         jedisCluster.set("name", "zhangsan");
         String value = jedisCluster.get("name");
         System.out.println(value);
    
       }

其它

客户端
  1. redis自带的客户端

    • 启动

      [root@andy bin]# ./redis-cli -h 127.0.0.1 -p 6379

      -h:指定访问的redis服务器的ip地址
      -p:指定访问的redis服务器的port端口
      还可以写成:[root@andy bin]# ./redis-cli
      使用默认配置:默认的ip【127.0.0.1】,默认的port【6379】

    • 关闭
      Ctrl+c

      127.0.0.1:6379> quit
  2. Jedis客户端
    jar包:commons-pool2-2.3.jar、jedis-2.7.0.jar
    单实例连接代码:

    @Test
    public void jedisClient(){
        //Jedis
        Jedis jedis = new Jedis("192.168.93.128", 6379);
        //通过redis赋值
        jedis.set("s2","2222");
        //通过redis取值
        String s2 = jedis.get("s2");
        System.out.println(s2);
        //关闭jedis
        jedis.close();
    }

    jedis连接池连接redis服务器:

    @Test
    public void jediPool(){
        //JedisPool
        JedisPool jedisPool = new JedisPool("192.168.93.128", 6379);
        //通过连接池获取jedis对象
        Jedis jedis = jedisPool.getResource();
        jedis.set("s4","4444");
        String s3 = jedis.get("s3");
        System.out.println(s3);
        //关闭jedis客户端
        jedis.close();
        //关闭连接池
        jedisPool.close();
    }
spring整合jedisPool:

添加spring的jar包

  1. spring配置文件applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
         http://www.springframework.org/schema/mvc 
         http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
         http://www.springframework.org/schema/context 
         http://www.springframework.org/schema/context/spring-context-3.2.xsd 
         http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
         http://www.springframework.org/schema/tx 
         http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
    
       <!-- 连接池配置 -->
       <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
         <!-- 最大连接数 -->
          <property name="maxTotal" value="30" />
         <!-- 最大空闲连接数 -->
          <property name="maxIdle" value="10" />
          <!-- 每次释放连接的最大数目 -->
          <property name="numTestsPerEvictionRun" value="1024" />
          <!-- 释放连接的扫描间隔(毫秒) -->
          <property name="timeBetweenEvictionRunsMillis" value="30000" />
         <!-- 连接最小空闲时间 -->
          <property name="minEvictableIdleTimeMillis" value="1800000" />
         <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
          <property name="softMinEvictableIdleTimeMillis" value="10000" />
         <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
          <property name="maxWaitMillis" value="1500" />
          <!-- 在获取连接的时候检查有效性, 默认false -->
          <property name="testOnBorrow" value="false" />
          <!-- 在空闲时检查有效性, 默认false -->
          <property name="testWhileIdle" value="true" />
          <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
          <property name="blockWhenExhausted" value="false" />
       </bean>
    
       <!-- redis单机 通过连接池 -->
       <bean id="jedisPool" class="redis.clients.jedis.JedisPool"
          destroy-method="close">
          <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
          <constructor-arg name="host" value="192.168.242.130" />
          <constructor-arg name="port" value="6379" />
       </bean>
    </beans>
  2. 测试代码

    @Test
    public void testJedisPool() {
        JedisPool pool = (JedisPool) applicationContext.getBean("jedisPool");
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            jedis.set("name", "lisi");
            String name = jedis.get("name");
            System.out.println(name);
         } catch (Exception ex) {
            ex.printStackTrace();
         } finally {
            if (jedis != null) {
               // 关闭连接
                jedis.close();
            }
         }
    
       }
keys命令
  1. keys,返回满足给定pattern 的所有key

    redis 127.0.0.1:6379> keys mylist*
    1) "mylist"
    2) "mylist5"
    3) "mylist6"
    4) "mylist7"
    5) "mylist8"
  2. exists,确认一个key 是否存在
    示例:从结果来看,数据库中不存在HongWan 这个key,但是age 这个key 是存在的

    redis 127.0.0.1:6379> exists HongWan
    (integer) 0
    redis 127.0.0.1:6379> exists age
    (integer) 1
    redis 127.0.0.1:6379>
  3. del,删除一个key

    redis 127.0.0.1:6379> del age
    (integer) 1
    redis 127.0.0.1:6379> exists age
    (integer) 0
  4. rename,重命名key
    示例:age 成功的被我们改名为age_new 了

    redis 127.0.0.1:6379[1]> keys *
    1) "age"
    redis 127.0.0.1:6379[1]> rename age age_new
    OK
    redis 127.0.0.1:6379[1]> keys *
    1) "age_new"
    redis 127.0.0.1:6379[1]>
  5. type,返回值的类型
    示例:这个方法可以非常简单的判断出值的类型

    redis 127.0.0.1:6379> type addr
    string
    redis 127.0.0.1:6379> type myzset2
    zset
    redis 127.0.0.1:6379> type mylist
    list
  6. 设置key的生存时间
    Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。

    EXPIRE key seconds               设置key的生存时间(单位:秒)key在多少秒后会自动删除
    TTL key                        查看key生于的生存时间
    PERSIST key                      清除生存时间 
    PEXPIRE key milliseconds    生存时间设置单位为:毫秒

    例子:

    192.168.101.3:7002> set test 1         设置test的值为1
    OK
    192.168.101.3:7002> get test           获取test的值
    "1"
    192.168.101.3:7002> EXPIRE test 5 设置test的生存时间为5秒
    (integer) 1
    192.168.101.3:7002> TTL test                查看test的生于生成时间还有1秒删除
    (integer) 1
    192.168.101.3:7002> TTL test
    (integer) -2
    192.168.101.3:7002> get test           获取test的值,已经删除
    (nil)
持久化方案
  1. rdb方式
    默认的方式,通过快照来将数据持久化到磁盘中。
    redis.conf中修改持久化快照的条件

    save 900 1  900秒修改一次则保存
    dbfilename dump.rdb
    dir ./ 
一旦redis非法关闭,那么会丢失最后一次持久化之后的数据
  1. aof方式
    操作一次redis数据库,则将操作的记录存储到aof持久化文件中。
    将redis.conf中的appendonly改为yes,即开启aof方式的持久化方案。
    在使用aof和rdb方式时,如果redis重启,则数据从aof文件加载。
主从复制

主机配置:无需配置
从机配置:

  1. 复制出一个从机

    [root@andy redis19]# cp bin/ bin2 –r
  2. 修改从机的redis.conf

    slaveof 192.168.242.137 6379
    port 6380
  3. 清除从机中的持久化文件

    [root@andy bin2]# rm -rf appendonly.aof dump.rdb
  4. 启动从机:

    [root@andy bin2]# ./redis-server redis.conf
  5. 启动6380的客户端:

    [root@andy bin2]# ./redis-cli -p 6380
注意:主机一旦发生增删改操作,那么从机会将数据同步到从机中,从机不能执行写操作


messchx
58 声望5 粉丝

« 上一篇
SpringMVC整理
下一篇 »
springboot注解