redis(1)

NoSql

为了解决高并发高可用高可扩展大数据存储等一系列问题而产生的数据库解决方案就是NoSql。

NoSql,叫非关系型数据库,它的全名Not only sql。它不能替代关系型数据库只能作为关系型数据库的一个良好补充。 

redis

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

键值类型

String字符类型

map散列类型

list列表类型

set集合类型

sortedset有序集合类型

 redis的应用场景

缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用

分布式集群架构中的session分离。 

聊天室的在线好友列表。

任务队列。(秒杀、抢购、12306等等) 

redis下载

官网地址:http://redis.io/

下载地址:http://download.redis.io/releases/redis-3.0.0.tar.gz

redis安装在linux上 

1.1 Redis安装

RedisC语言开发,建议在linux上运行,本教程使用Centos6.4作为安装环境。

第一步安装VMware,并且在VMware中安装centos系统(参考linux教程)。

第二步:将redis的压缩包,上传到linux系统

第三步redis的压缩包进行解压缩

Redis解压缩之后的文件是用c语言写的源码文件

 tar -zxf redis-3.0.0.tar.gz

第四步安装c语言环境(安装centos之后,自带c语言环境)

 yum install gcc-c++

第五步编译redis源码

cd redis-3.0.0

 make

第六步:安装redis

 make install PREFIX=/usr/local/redis19

第七步查看是否安装成功

  

redis启动 

前端启动的命令

./redis-server 

前端启动的关闭

强制关闭:Ctrl+c

./redis-cli shutdown

启动界面

  后端启动

第一步需要将redis解压之后的源码包中的redis.conf文件拷贝到bin目录下

[root@itheima bin]# cp /root/redis-3.0.0/redis.conf ./

第二步修改redis.conf文件daemonize改为yes

先要使用vim redis.conf

 

第三步使用命令后端启动redis

[root@itheima bin]# ./redis-server redis.conf

第四步查看是否启动成功

 

强制关闭:kill -9 5071

正常关闭: ./redis-cli shutdown

 Redis自带的客户端

启动 

启动客户端命令: ./redis-cli -h 127.0.0.1 -p 6379

-h:指定访问的redis服务器的ip地址

-p:指定访问的redis服务器的port端口

还可以写成: ./redis-cli

使用默认配置默认的ip127.0.0.1】,默认的port6379

关闭 

Ctrl+c

127.0.0.1:6379> quit

 jedis介绍

 

@Test
    public void testJedis() {
        //创建一个Jedis的连接
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        //执行redis命令
        jedis.set("mytest", "hello world, this is jedis client!");
        //从redis中取值
        String result = jedis.get("mytest");
        //打印结果
        System.out.println(result);
        //关闭连接
        jedis.close();
        
    }

 连接池连接

@Test
    public void testJedisPool() {
        //创建一连接池对象
        JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
        //从连接池中获得连接
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get("mytest");
        System.out.println(result);
        //关闭连接
        jedis.close();
        
        //关闭连接池
        jedisPool.close();
    }

Spring整合jedisPool

  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>
@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();
            }
        }
    }

 Redis数据类型

Redis中存储数据是通过key-value存储的对于value的类型有以下几种

  • 字符串
  • Hash类型
  • List
  • Set
  • SortedSetzset
  • String类型

     语法:SET key value

127.0.0.1:6379> set test 123
OK

  语法:GET key

127.0.0.1:6379> get test
"123“

语法

MSET key value [key value …]

MGET key [key …]

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> mget k1 k3
1) "v1"
2) "v3"

语法:GETSET key value 赋值并取值

127.0.0.1:6379> getset s2 222
"111"
127.0.0.1:6379> get s2
"222"

语法:DEL key 删除

127.0.0.1:6379> del test
(integer) 1

语法:INCR key 增减

127.0.0.1:6379> incr num
(integer) 1
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> incr num
(integer) 3

语法:INCRBY key increment    增加指定的整数

127.0.0.1:6379> incrby num 2
(integer) 5
127.0.0.1:6379> incrby num 2
(integer) 7
127.0.0.1:6379> incrby num 2
(integer) 9

语法:DECR key   递减数值

127.0.0.1:6379> decr num
(integer) 6
127.0.0.1:6379> decr num
(integer) 5
127.0.0.1:6379> decrby num 3
(integer) 2
127.0.0.1:6379> decrby num 3
(integer) -1

语法:APPEND key value

127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> append str " world!"
(integer) 12
127.0.0.1:6379> get str 
"hello world!

语法:STRLEN key   返回键值的长度,如果键不存在则返回0

127.0.0.1:6379> strlen str 
(integer) 0
127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> strlen str 
(integer) 5

商品编号、订单号采用string的递增数字特性生成。

定义商品编号keyitems:id

192.168.101.3:7003> INCR items:id
(integer) 2
192.168.101.3:7003> INCR items:id
(integer) 3

Hash

hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型。

语法:HSET key field value 

127.0.0.1:6379> hset user username zhangsan 
(integer) 1

语法:HMSET key field value [field value ...]

127.0.0.1:6379> hmset user age 20 username lisi 
OK

语法:HSETNX key field value

127.0.0.1:6379> hsetnx user age 30    如果user中没有age字段则设置age值为30,否则不做任何操作
(integer) 0

语法:HGET key field

127.0.0.1:6379> hget user username
"zhangsan“

语法:HMGET key field [field ...]

127.0.0.1:6379> hmget user age username
1) "20"
2) "lisi"

语法:HGETALL key

127.0.0.1:6379> hgetall user
1) "age"
2) "20"
3) "username"
4) "lisi"

语法:HDEL key field [field ...]

127.0.0.1:6379> hdel user age
(integer) 1
127.0.0.1:6379> hdel user age name
(integer) 0
127.0.0.1:6379> hdel user age username
(integer) 1 

语法:HINCRBY key field increment

127.0.0.1:6379> hincrby user age 2    将用户的年龄加2
(integer) 22
127.0.0.1:6379> hget user age        获取用户的年龄
"22“

语法:HEXISTS key field

127.0.0.1:6379> hexists user age        查看user中是否有age字段
(integer) 1
127.0.0.1:6379> hexists user name    查看user中是否有name字段
(integer) 0

语法

HKEYS key

HVALS key

27.0.0.1:6379> hmset user age 20 name lisi 
OK
127.0.0.1:6379> hkeys user
1) "age"
2) "name"
127.0.0.1:6379> hvals user
1) "20"
2) "lisi"

语法:HLEN key

127.0.0.1:6379> hlen user
(integer) 2
  • 存储商品信息
192.168.101.3:7003> HMSET items:1001 id 3 name apple price 999.9
OK
  • 获取商品信息
192.168.101.3:7003> HGET items:1001 id
"3"
192.168.101.3:7003> HGETALL items:1001
1) "id"
2) "3"
3) "name"
4) "apple"
5) "price"
6) "999.9"

 List

Redislist是采用来链表来存储的,所以对于redislist数据类型的操作,是操作list的两端数据来操作的。

语法:LPUSH key value [value ...]   列表左边增加元素 

127.0.0.1:6379> lpush list:1 1 2 3
(integer) 3

语法RPUSH key value [value ...]  列表右边增加元素 

127.0.0.1:6379> rpush list:1 4 5 6
(integer) 3

语法:LRANGE key start stop    获取列表中的某一片段

127.0.0.1:6379> lrange list:1 0 2
1) "2"
2) "1"
3) "4"

127.0.0.1:6379> lrange list1 0 -1

语法

LPOP key

RPOP key

LPOP命令从列表左边弹出一个元素,会分两步完成:

第一步是将列表左边的元素从列表中移除

第二步是返回被移除的元素值。

127.0.0.1:6379> lpop list:1
"3“
127.0.0.1:6379> rpop list:1
"6“

语法:LLEN key  获取元素个数

127.0.0.1:6379> llen list:1
(integer) 2

LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同: 

l 当count>0时, LREM会从列表左边开始删除。 

l 当count<0时, LREM会从列表后边开始删除。 

l 当count=0时, LREM删除所有值为value的元素。 

语法:LREM key count value

语法:LINDEX key index

127.0.0.1:6379> lindex l:list 2
"1"

语法:LSET key index value   设置指定索引的元素值

127.0.0.1:6379> lset l:list 2 2
OK
127.0.0.1:6379> lrange l:list 0 -1
1) "6"
2) "5"
3) "2"
4) "2"

语法:LTRIM key start stop    指定范围和LRANGE一致 

127.0.0.1:6379> lrange l:list 0 -1     获取
1) "6"
2) "5"
3) "0"
4) "2"
127.0.0.1:6379> ltrim l:list 0 2
OK
127.0.0.1:6379> lrange l:list 0 -1
1) "6"
2) "5"
3) "0"

语法LINSERT key BEFORE|AFTER pivot value  插入

127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> linsert list after 3 4
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "4"
3) "2"
4) "1"

语法RPOPLPUSH source destination   

将元素从一个列表转移到另一个列表中 

127.0.0.1:6379> rpoplpush list newlist 
"1"
127.0.0.1:6379> lrange newlist 0 -1
1) "1"
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "4"
3) "2"

商品编号为1001的商品评论keyitems: comment:1001

192.168.101.3:7001> LPUSH items:comment:1001 '{"id":1,"name":"商品不错,很好!!","date":1430295077289}'

Set

集合类型:无序、不可重复

列表类型有序可重复

语法SADD key member [member ...]

127.0.0.1:6379> sadd set a b c
(integer) 3
127.0.0.1:6379> sadd set a
(integer) 0

语法SREM key member [member ...]

127.0.0.1:6379> srem set c d
(integer) 1

语法SMEMBERS key  获取所有元素

127.0.0.1:6379> smembers set
1) "b"
2) "a”

语法SISMEMBER key member 判断是否在集合中

127.0.0.1:6379> sismember set a
(integer) 1
127.0.0.1:6379> sismember set h
(integer) 0

语法SDIFF key [key ...]  差集

127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB 
1) "1"
127.0.0.1:6379> sdiff setB setA 
1) "4"

语法:SINTER key [key ...] 交集

127.0.0.1:6379> sinter setA setB 
1) "2"
2) "3"

语法:SUNION key [key ...] 并集

127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"

语法SCARD key  获取集合中的个数

127.0.0.1:6379> smembers setA 
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> scard setA 
(integer) 3

语法SPOP key 随机跳出一个集合中的元素

127.0.0.1:6379> spop setA 
"1“

Sortedset 

Sortedset又叫zset

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

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

语法ZADD key score member [score member ...]

127.0.0.1:6379> zadd scoreboard 80 zhangsan 89 lisi 94 wangwu 
(integer) 3
127.0.0.1:6379> zadd scoreboard 97 lisi 
(integer) 0

语法:ZSCORE key member  获取

127.0.0.1:6379> zscore scoreboard lisi 
"97"

语法:ZREM key member [member ...]

127.0.0.1:6379> zrem scoreboard lisi
(integer) 1

语法ZRANGE key start stop [WITHSCORES]

127.0.0.1:6379> zrange scoreboard 0 2
1) "zhangsan"
2) "wangwu"
3) "lisi“ 

语法ZREVRANGE key start stop [WITHSCORES]

127.0.0.1:6379> zrevrange scoreboard 0 2
1) " lisi "
2) "wangwu"
3) " zhangsan “

如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数 

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

语法ZRANK key member  获取排名

127.0.0.1:6379> ZRANK scoreboard lisi 
(integer) 0

语法ZREVRANK key member  反向获取排名

127.0.0.1:6379> ZREVRANK scoreboard zhangsan 
(integer) 1

语法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

应用 商品销售排行榜 

写入商品销售量

  • 商品编号1001的销量是9,商品编号1002的销量是10
192.168.101.3:7007> ZADD items:sellsort 9 1001 10 1002
  • 商品编号1001的销量加1
192.168.101.3:7001> ZINCRBY items:sellsort 1 1001
  • 商品销量前10名:
192.168.101.3:7001> ZRANGE items:sellsort 0 9 withscores

 Keys命令

keys

返回满足给定pattern 的所有key

redis 127.0.0.1:6379> keys mylist*
1) "mylist"
2) "mylist5"
3) "mylist6"
4) "mylist7"
5) "mylist8"

 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>

 del

删除一个key

redis 127.0.0.1:6379> del age
(integer) 1
redis 127.0.0.1:6379> exists age
(integer) 0

 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]>

 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
redis 127.0.0.1:6379>

设置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)
原文地址:https://www.cnblogs.com/hudj/p/7436225.html