Redis

Redis

1、介绍

Redis是NoSQL中的一种,使用Key-value类型存储数据,基于内存的具有高性能数据库,可以定制持久化到磁盘的策略。支持的类型丰富多样,例如list、set、hash、zset等。读操作速度可达110,000/s,写入速度可达80,000/s。

2、Redis安装

2.1 windows

  1. 解压redis-2.2.2-win32-win64.rar

  2. 配置环境变量path

  3. 启动redis服务器

    cmd>redis-server.exe

  4. 启动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 安装
  1. 先安装gcc编译器

    $>sudo yum install -y gcc
    
  2. 编译安装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

效果如图所示:

redis_002

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脚本,切记是该文件在源代码目录中,如下图所示:

redis_003

执行如下命令,将各节点加入集群部落:

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

执行效果图如下:

redis_003

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

redis_003

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数据库,基于内存的数据库。在很多企业中通常用作缓存,提供系统的响应时间。同时由于其简单易用性,普遍受到企业的青睐。

原文地址:https://www.cnblogs.com/xupccc/p/9543951.html