简介
export LANG=zh_CN.gbk
192.168.**.128
systemctl stop firewalld.service
为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,就是NoSql。它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。
Redis是使用c语言开发的一个高性能键值数据库。Redis可以通过一些键值类型来存储数据。
键值类型:
- String字符类型
- hash散列类型
- list列表类型
- set集合类型
- sortedset有序集合类型
应用场景
- 缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
- 分布式集群架构中的session分离。
- 聊天室的在线好友列表。
- 任务队列。(秒杀、抢购、12306等等)
- 应用排行榜。
- 网站访问统计。
- 数据过期处理(可以精确到毫秒)
安装
- 解压缩: #tar -zxf redis-3.0.0.tar.gz
- 安装c语言环境:#yum install gcc-c++
-
编译redis源码:
cd redis-3.0.0
make
- 安装redis:#make install PREFIX=/usr/local/redis
- 前端启动redis,在bin目录下:# ./redis-server
强制关闭:Ctrl+c,一旦客户端关闭,则redis服务也停掉。 - 后端启动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
数据类型
- 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 - 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 - 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 - 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命令会从集合中随机选择一个元素弹出 -
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脚本语言编写的。
-
安装ruby
[root@andy bin2]# yum install ruby [root@andy bin2]# yum install rubygems
- 将redis安装包上传到linux系统
redis-3.0.0.gem -
安装ruby和redis接口
[root@andy ~]# gem install redis-3.0.0.gem
-
将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
- 复制出一个7001机器
[root@andy redis19]# cp bin ./redis-cluster/7001 –r - 如果存在持久化文件,则删除
[root@andy 7001]# rm -rf appendonly.aof dump.rdb - 设置集群参数
cluster-enabled yes - 修改端口
port 7001 - 复制出7002-7006机器
- 修改7002-7006机器的端口
-
启动7001-7006这六台机器
创建启动文件,start-all.shcd 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 ..
-
修改start-all.sh文件的权限
[root@andy redis-cluster]# chmod u+x start-all.sh [root@andy redis-cluster]# ./start-all.sh
-
创建集群
[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); }
其它
客户端
-
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+c127.0.0.1:6379> quit
-
-
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包
-
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>
-
测试代码
@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命令
-
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
-
设置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)
持久化方案
-
rdb方式
默认的方式,通过快照来将数据持久化到磁盘中。
redis.conf中修改持久化快照的条件save 900 1 900秒修改一次则保存 dbfilename dump.rdb dir ./
一旦redis非法关闭,那么会丢失最后一次持久化之后的数据
- aof方式
操作一次redis数据库,则将操作的记录存储到aof持久化文件中。
将redis.conf中的appendonly改为yes,即开启aof方式的持久化方案。
在使用aof和rdb方式时,如果redis重启,则数据从aof文件加载。
主从复制
主机配置:无需配置
从机配置:
-
复制出一个从机
[root@andy redis19]# cp bin/ bin2 –r
-
修改从机的redis.conf
slaveof 192.168.242.137 6379 port 6380
-
清除从机中的持久化文件
[root@andy bin2]# rm -rf appendonly.aof dump.rdb
-
启动从机:
[root@andy bin2]# ./redis-server redis.conf
-
启动6380的客户端:
[root@andy bin2]# ./redis-cli -p 6380
注意:主机一旦发生增删改操作,那么从机会将数据同步到从机中,从机不能执行写操作
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。