Redis
1、介绍
Redis是NoSQL中的一种,使用Key-value类型存储数据,基于内存的具有高性能数据库,可以定制持久化到磁盘的策略。支持的类型丰富多样,例如list、set、hash、zset等。读操作速度可达110,000/s,写入速度可达80,000/s。
2、Redis安装
2.1 windows
-
解压redis-2.2.2-win32-win64.rar
-
配置环境变量path
-
启动redis服务器
cmd>redis-server.exe
-
启动redis客户端
cmd>redis-client.exe
2.2 linux
2.2.1 下载软件包
redis-3.2.8.tar.gz
2.2.2 tar开文件到指定目录
$>sudo tar -xzvf redis-3.2.8.tar.gz -C ~
2.2.3 安装
-
先安装gcc编译器
$>sudo yum install -y gcc
-
编译安装redis
$>su root $>cd ~/redis-3.2.8 #指定安装目录 $>make PREFIX=/soft/redis-3.2.8 install
2.2.4 创建软连接
$>ln -s redist-3.2.8 redis
2.2.5 配置环境变量
[/etc/profile]
...
export REDIS_HOME=/soft/redis
export PATH=$PATH:$REDIS_HOME/bin
2.2.6 启动redis服务器
$>redis-server &
2.2.7 启动client
$>redis-cli -h localhost -p 6379
2.2.8 体验redis-ping-pang
输入ping,输出pang!
$redis>ping
3、redis管理命令
3.1 常用命令
3.1.1 帮助命令
#查看所有帮助
$redis>help
#自动补全
$redis>help @[tab]
#查看命令组
$redis>help @generic
#查看特定命令
$redis>help ping
3.1.2 key操作
#set
$redis>set key1 tom1
#get
$redis>get key1
#所有key
$redis>keys *
#正则key
$redis>keys user*
#key是否存在
$redis>exsists key1
#删除key
$redis>del key1
#随机提取key
$redis>randomkey
#重命名key
$redis>rename key1 key_1
#查看key的类型
$redis>type key1
3.1.3 库操作
#选择库
$redis>select 0
#移动kv到指定的库中
$redis>move key1 1
#删除当前库的所有key
$redis>flushdb
#删除所有库的所有key
$redis>flushall
#同步保存数据到磁盘(前台保存)
$redis>save
#异步保存数据到磁盘(后台保存)
$redis>bgsave
#清屏
$redist>clear
#退出redis
$redis>quit
#返回数据库key的数量
$redis>dbsize
#返回ku信息
$redis>info
3.2 保护模式
保护模式下的redis不允许远程连接,需要关闭保护模式。
3.2.1 临时关闭
命令关闭只对当前库有效,下次启动还需要手动关闭。
#查看保护模式
$redis>config get protected-mode
#设置保护模式
$redis>config set protected-mode no
3.2.2 永久关闭
配置文件的方式就是永久关闭。
[/soft/redis/conf/redis.conf]
#关闭保护模式
protected-mode no
3.3 保存文件的位置和名称
redis默认在启动redis-server时,将当前目录作为保存数据文件的目录,并且文件名默认为dump.rdb。可以通过如下的属性进行修改:
[/soft/rediss/conf/redis.conf]
...
#指定保存的文件名
dbfilename dump.rdb
#指定保存的目录,默认当前目录
dir ./
4、redis数据类型
4.1 hash
hash类型是redis中最常用的类型,类似于hashmap,使用多个字段与值构成的映射集合。
4.1.1 hset
设置key下value中的一个字段和值。
127.0.0.1:6379>hset uesr_0 id 1000
4.1.2 hmset
设置value中的多个值,m表示multiple之意。
127.0.0.1:6379>hset uesr_0 id 1000 name tomas age 12
4.1.3 hget
提取value中一个值。
127.0.0.1:6379>hget user_0 id
4.1.4 hmget
提取value中的多个字段值,m表示multiple之意。
127.0.0.1:6379>hget user_0 id name age
4.1.5 hkeys
显式hash中的所有key。
127.0.0.1:6379>hkeys user_0
4.1.6 hgetall
显式hash中所有的key和value。
127.0.0.1:6379>hgetall user_0
4.1.7 hdel
删除hash中一个或多个字段。
127.0.0.1:6379>hdel user_0 id name age
4.1.8 hexists
判断hash中的key是否存在 。
127.0.0.1:6379>hexists user_0 id
4.1.9 hincrby
给hash中指定字段增加指定的整数量值。
127.0.0.1:6379>hincrby user_0 id 20
4.1.10 HINCRBYFLOAT
给hash中指定字段增加指定的浮点数量值。
127.0.0.1:6379>hincrbyfloat user_0 id 20.5
4.1.11 hlen
计算hash集合中字段的个数。
127.0.0.1:6379>hlen user_0
4.1.12 hsetnx
同hset,但只针对不存在的字段。nx表示not exists。
127.0.0.1:6379>hsetnx user_0 name tomasLee
4.1.13 hstrlen
获取指定字段的值的字符串长度。
127.0.0.1:6379>hstrlen user_0 name
4.1.14 hvals
列出hash的所有value。
127.0.0.1:6379>hvals user_0
4.2 list
list集合有顺序,可以存放重复元素。类似于java中的List集合。
4.2.1 lpush
向list中压入元素。l表示list,push是压栈操作。
127.0.0.1:6379>lpush list1 tom1 tom2 tom3
4.2.2 lrange
列出指定范围的元素,使用索引作为参数。范围是闭区间。
#显式所有元素
127.0.0.1:6379>lrange list1 0 -1
4.2.3 blpop
同步弹出元素。b表示block,阻塞。
127.0.0.1:6379>blpop list1
4.2.4 brpoplpush
弹出list1的右侧元素到list2中,返回弹出的元素。b为block,r为right,pop为弹出,lpush是压入元素。
127.0.0.1:6379>brpoplpush list1 list2 200
4.2.5 rpoplpush
弹出右侧元素压入list2中,同上,但不是同步操作。
127.0.0.1:6379>rpoplpush list1 list2 200
4.2.6 lpop
弹出list中的第一个元素。
127.0.0.1:6379>lpop list1
4.2.7 linsert
在指定的元素的位置前或后插入元素,如在list1的tom2之前插入元素tom22。
127.0.0.1:6379>linsert list1 before tom2 tom22
4.2.8 llen
查询list元素的个数。
127.0.0.1:6379>llen list1
4.3 set
set集合无顺序,元素不能重复。类似于java中的Set集合。
4.3.1 sadd
添加元素到set集合中。
127.0.0.1:6379>sadd s1 tom1 tom1 tom2
4.3.2 smember
查看set中的所有成员。
127.0.0.1:6379>smember s1
4.3.3 scard
查看set集合的元素个数。
127.0.0.1:6379>scard s1
4.3.4 sdiff
两个set集合的差集。例如(1,2,3) - (2,3,4) = (1)
#set1
127.0.0.1:6379>sadd s1 1 2 3
#set2
127.0.0.1:6379>sadd s1 2 3 4
#差集
127.0.0.1:6379>sdiff s1 s2
4.3.5 sdiffstore
计算差集并存储到新的set中。
127.0.0.1:6379>sdiffstore s1 s2 s3
4.3.6 sinter
计算两个set的交集。
127.0.0.1:6379>sinter s1 s2
4.3.7 sinterstore
计算交集并存储到新集合。
127.0.0.1:6379>sinter s1 s2 s3
4.3.8 sismember
判断指定元素是否是set中的成员。
127.0.0.1:6379>sismember s1 tom2
4.3.9 srem
从set中删除指定的元素。
127.0.0.1:6379>srem s1 tom2
4.3.10 sscan
增量迭代集合元素。
127.0.0.1:6379>sscan s1 0 match tom* 2
4.3.11 sunion
计算两个set的并集。
127.0.0.1:6379>sunion s1 s2
4.3.12 sunionstore
计算并集并存储到新集合。
127.0.0.1:6379>sunion s1 s2 s3
4.4 zset
zset是有序集合,但仍然不能重复,通过给每个元素关联一个打分实现排序处理。
4.4.1 zadd
添加元素到zset集合。
127.0.0.1:6379>zadd z1 1 tom1 2 tom2
4.4.2 zrange
查看指定范围的zset集合,可以指定是否携带分值。
127.0.0.1:6379>zrange z1 0 -1 withscores
4.4.3 zcard
查看zset集合中元素的个数。
127.0.0.1:6379>zcard z1
4.4.4 zcount
计算zset集合中分值在指定范围中的元素的个数。
127.0.0.1:6379>acount z1 10 20
4.4.5 zincrby
增加指定元素的分值。
127.0.0.1:6379>zincrby z1 2 tom1
4.4.6 zrank
查找指定索引范围的成员。
127.0.0.1:6379>zrank z1 0 -1 withscores
4.4.7 zrem
删除元素。
127.0.0.1:6379>zrem z1 tom1 tom2
4.4.8 zremrangebylex
按照索引范围删除元素。
127.0.0.1:6379>zremrangebylex z1 [tom1 (tom2
4.4.9 zremrangebyrank
按照排名删除元素。
127.0.0.1:6379>zremrangebyrank z1 0 -1
4.4.10 zremrangebyscore
按照分值删除元素。
127.0.0.1:6379>zremrangebyscore z1 100 200
4.4.11 zrevrange
倒序排列。
127.0.0.1:6379>zrevrange z1 0 -1 withscores
5、发布订阅消息
redis可以实现消息的订阅和发布。启动两个终端,一个终端进行订阅,另外一个发布消息,这个过程中需要使用同一个通道。
#订阅 终端1--进入订阅模式
127.0.0.1:6379>subscribe c1
#发布终端 , c1是通道,hello word是消息
127.0.0.1:6379>publish c1 hello world
效果如图所示:
6、redis集群搭建
redis支持集群配置,这里使用的集群配置方式是master-slave模式,每个master对应一个slave节点,至少需要6个redis节点。
6.1 创建配置目录存放不同的配置文件
创建的配置目录和文件如下所示:
#
/soft/redis/conf/7000/redis.conf
/soft/redis/conf/7001/redis.conf
/soft/redis/conf/7002/redis.conf
/soft/redis/conf/7003/redis.conf
/soft/redis/conf/7004/redis.conf
/soft/redis/conf/7005/redis.conf
6.2 修改配置文件
修改每个配置文件,设置相应的参数,比如监听端口、pid进程文件、绑定地址、数据库文件等。
6.2.1 redis配置文件
redis配置文件有如下几部分配置项,内容如下:
-
INCLUDES
文件头导入部分,这里不需要修改。
-
NETWORK
修改绑定地址、保护模式、监听端口等,配置如下:
################################## NETWORK ##################################### #绑定地址 bind 192.168.231.101 #关闭保护模式 protected-mode no #监听端口 port 7000
-
GENERAL
配置redis为守护进程,指定pid存放文件。
################################# GENERAL ##################################### #守护进程 daemonize yes #pid文件 pidfile /var/run/pid_7000.pid #数据库数量 databases 16
-
SNAPSHOTTING
可以配置数据库文件。
################################ SNAPSHOTTING ################################ #数据库文件名 dbfilename dump.rdb #存放目录 dir ./
-
REPLICATION
控制主从复制,不需要修改。
-
SECURITY
安装控制,无需修改。
-
LIMITS
限制客户单数量,内存等参数,不需要修改。
-
APPEND ONLY MODE
以追加方式写入文件,一种防丢失处理,不需要修改。
-
LUA SCRIPTING
LUA脚本执行时间控制,不需要修改。
-
REDIS CLUSTER
Redis集群控制。默认情况下,redis实例不是集群中的一部分,必须以集群节点的方式启动才可以。因此,需要启用一下配置:
################################ REDIS CLUSTER ############################### #启用集群 cluster-enabled yes #集群生成的配置文件名 cluster-config-file nodes-7000.conf
-
SLOW LOG
log控制,不需要配置。
-
LATENCY MONITOR
延迟监视配置,不需要配置。
-
EVENT NOTIFICATION
事件通知配置,不需要配置。
-
ADVANCED CONFIG
高级配置项,不需要配置。
6.2.2 完整配置文件
################################## INCLUDES ###################################
################################## NETWORK #####################################
bind 192.168.231.101
protected-mode no
port 7000
tcp-backlog 511
timeout 0
tcp-keepalive 300
################################# GENERAL #####################################
daemonize yes
supervised no
pidfile /var/run/redis_7000.pid
loglevel notice
logfile ""
databases 16
################################ SNAPSHOTTING ################################
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump_7000.rdb
dir ./
################################# REPLICATION #################################
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
################################## SECURITY ###################################
################################### LIMITS ####################################
############################## APPEND ONLY MODE ###############################
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
################################ LUA SCRIPTING ###############################
lua-time-limit 5000
################################ REDIS CLUSTER ###############################
cluster-enabled yes
cluster-config-file nodes-7000.conf
################################## SLOW LOG ###################################
slowlog-log-slower-than 10000
slowlog-max-len 128
################################ LATENCY MONITOR ##############################
latency-monitor-threshold 0
############################# EVENT NOTIFICATION ##############################
notify-keyspace-events ""
############################### ADVANCED CONFIG ###############################
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
6.2.3 使用命令进行替换
可以使用linux的sed命令进行快速替换操作。
#-i表示替换,将6379替换成7000。
$>sed -i 's/6379/7000/g' redis.conf
6.3 启动所有redis server
使用不同的配置文件分别启动六个redis服务器,命令如下:
$>su root
$>redis-server redis_7000.conf
$>redis-server redis_7001.conf
$>redis-server redis_7002.conf
$>redis-server redis_7003.conf
$>redis-server redis_7004.conf
$>redis-server redis_7005.conf
6.4 安装gem,将redis服务器并入集群
6.4.1 安装gem软件包
$>sudo yum install -y gem
6.4.2 删除旧的gem源
$>sudo gem sources --remove https://rubygems.org/
6.4.3 添加新的gem源
$>sudo gem sources -a https://gems.ruby-china.org/
6.4.4 使用gem安装redis 3.0.0 版本
$>sudo gem install redis --version 3.0.0
6.4.5 将各主机上的redis进程加入集群部落
执行redis源代码目录下的redis-trib.rb脚本,切记是该文件在源代码目录中,如下图所示:
执行如下命令,将各节点加入集群部落:
$>su root
$>cd /home/centos/redis-3.2.8
$>/home/centos/redis-3.2.8/src/redis-trib.rb create --replicas 1 192.168.231.101:7000 192.168.231.101:7001 192.168.231.101:7002 192.168.231.101:7003 192.168.231.101:7004 192.168.231.101:7005
执行效果图如下:
6.4.6 启动客户端连接到集群
#-c表示启用集群,-h连接主机 -p连接端口
$>redis-cli -c -h 192.168.231.101 -p 70000
6.4.7 执行key操作,考察集群重定向
对key操作时,会对key进行hash计算,重定向到相应的redis服务器进行存储。如下图所示:
192.168.231.101:7000>set key1 tom1
7、管理redis集群的脚本
redis集群涉及到很多redis server进程操作,每次开启和关闭都比较繁琐,可以编写shell脚本,实现redis集群的启动和停止,也可以在命令行中直接完成,如下代码所示:
7.1 启动redis集群
$>su root
$>for x in 0 1 2 3 4 5 ; do redis-server 700$x/redis.conf ; done
7.2 杀死所有redis服务器进程
$>su root
$>netstat -anop |grep 700 |grep LIST | awk '{print $7}' | awk -F / '{print $1}' | kill -9 `xargs`
7.3 查看所有redis进程
$>su root
$>netstat -anop |grep 700 |grep LIST
7.4 编写redis集群脚本
7.4.1 启动集群脚本
[/soft/redis/bin/redis-cluster-start.sh]
#!/bin/bash
for x in 0 1 2 3 3 4 5 ;do redis-server /soft/redis/conf/700$x/redis.conf ; done
7.4.2 停止集群脚本
找出所有redis-server进程,然后将其杀死。
[/soft/redis/bin/redis-cluster-stop.sh]
#!/bin/bash
netstat -anop | grep 700 | gret LIST | grep redis-server | awk '{print $7}' | awk -F / '{print $1}' | kill -9 `xargs`
7.4.3 初始化集群脚本
集群首次创建时,需要将redis-server进程并入到redis集群。以后就不需要此过程。
#!/bin/bash
/home/centos/redis-3.2.8/src/redis-trib.rb create --replicas 1 192.168.231.101:7000 192.168.231.101:7001 192.168.231.101:7002 192.168.231.101:7003 192.168.231.101:7004 192.168.231.101:7005
7.4.4 查看集群进程脚本
查看redis集群进程是否还在。
#!/bin/bash
netstat -anop | grep 700 | gret LIST | grep redis-server
8、使用java代码连接到redis集群
连接到redis集群需要指定多个redis节点的地址。
8.1 引入maven依赖
redis cluster API在redis-cli的2.9.0版本中,因此需要修改maven的依赖文件。
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
8.2 使用cluster API
import org.junit.Test;
import redis.clients.jedis.BinaryJedisCluster;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisMonitor;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
public void getRedisCluster() throws Exception {
Set<HostAndPort> hosts = new HashSet<HostAndPort>();
hosts.add(new HostAndPort("192.168.231.101", 7000));
hosts.add(new HostAndPort("192.168.231.101", 7001));
hosts.add(new HostAndPort("192.168.231.101", 7002));
hosts.add(new HostAndPort("192.168.231.101", 7003));
hosts.add(new HostAndPort("192.168.231.101", 7004));
hosts.add(new HostAndPort("192.168.231.101", 7005));
BinaryJedisCluster cluster = new BinaryJedisCluster(hosts);
byte[] value = cluster.get("key1".getBytes()) ;
System.out.println(new String(value));
cluster.close();
}
9、总结
redis是NoSQL数据库,基于内存的数据库。在很多企业中通常用作缓存,提供系统的响应时间。同时由于其简单易用性,普遍受到企业的青睐。