一、redis部署与使用

1.1:redis基础

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

Redis和Memcached是非关系型数据库也称为NoSQL数据库,MySQL、Mariadb、SQL Server、PostgreSQL、Oracle 数据库属于关系型数据(RDBMS, Relational Database Management System)
1.1.1:redis简介

redis是一个开源的、遵循BSD协议的、基于内存的而且目前比较流行的键值数据库(key-value database),是一个非关系型数据库,redis提供将内存通过网络远程共享的一种服务,提供类似功能的还有memcache,但相比memcache,redis还提供了易扩展、高性能、具备数据持久性等功能。
1.1.2:redis对比memcached

支持数据的持久化:可以将内存中的数据保持在磁盘中,重启redis服务或者服务器之后可以从备份文件中恢复数据到内存继续使用。支持更多的数据类型:支持string(字符串)、hash(哈希数据)、list(列表)、set(集合)、zet(有序集合)
支持数据的备份:可以实现类似于数据的master-slave模式的数据备份,另外也支持使用快照+AOF。
支持更大的value数据:memcache单个key value最大只支持1MB,而redis最大支持512MB。
Redis 是单线程,而memcache是多线程,所以单机情况下没有memcache并发高,但redis 支持分布式集群以实现更高的并发,单Redis实例可以实现数万并发。
支持集群横向扩展:基于redis cluster的横向扩展,可以实现分布式集群,大幅提升性能和数据安全性。
都是基于C语言开发。

1.2:Redis安装及使用

官方下载地址:http://download.redis.io/releases/

1.2.1:编译安装redis

 Redis的安装非常方便,只需获取源码,然后make && make install即可。默认情况下,Redis的服务器启动程序和客户端程序会安装到/usr/local/bin目录下。在启动Redis服务器时,我们需要为其指定一个配置文件,缺省情况下配置文件在Redis的源码目录下,文件名为redis.conf。下载当前release版本redis 源码包:http://download.redis.io/releases/

MySQL Redis 关系型数据库 非关系型数据库 redis是不是非关系型数据库_Redis

1.2.1.1:编译安装命令

# pwd
/usr/local/src
# tar xf redis-4.0.14.tar.gz
# cd redis-4.0.14
#yum install gcc -y
#yum install jemalloc -y
#make MALLOC=libc
# make PREFIX=/app/redis install #指定redis安装目录
# mkdir /apps/redis/{etc,logs,data,run} #创建配置文件、日志、数据等目录
# cp redis.conf /usr/local/redis/etc/

1.2.1.2:前台启动redis

[root@localhost redis-4.0.14]#  /app/redis/bin/redis-server /usr/local/src/redis-4.0.14/redis.conf

MySQL Redis 关系型数据库 非关系型数据库 redis是不是非关系型数据库_数据_02

1.2.1.3:解决当前的警告提示

5289:M 11 Feb 16:02:44.672 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
5289:M 11 Feb 16:02:44.672 # Server initialized
5289:M 11 Feb 16:02:44.672 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

第一个WARNING:

vim etc/sysctl.conf
net.core.somaxconn = 1024

第二个WARNNING:

vim  /etc/sysctl.conf
vm.overcommit_memory = 1
sysctl -p

1.2.1.4:再次启动redis

成功启动

MySQL Redis 关系型数据库 非关系型数据库 redis是不是非关系型数据库_Redis_03

   1.2.1.5:编辑redis服务启动脚本 

[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/app/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target

1.2.1.6:创建redis 用户

groupadd -g 1000 redis && useradd -u 1000 -g 1000 redis -s /sbin/nologin
chown redis.redis -R /app/redis/

1.2.1.7:验证是否redis启动

MySQL Redis 关系型数据库 非关系型数据库 redis是不是非关系型数据库_redis_04

 1.2.1.8:使用客户端连接redis

/app/redis/bin/redis-cli -h IP/HOSTNAME -p PORT -a PASSWORD

1.2.1.9:创建命令软连接(以便全局使用)

[root@localhost redis]# ln -sv /app/redis/bin/redis-* /usr/bin/
‘/usr/bin/redis-benchmark’ -> ‘/app/redis/bin/redis-benchmark’
‘/usr/bin/redis-check-aof’ -> ‘/app/redis/bin/redis-check-aof’
‘/usr/bin/redis-check-rdb’ -> ‘/app/redis/bin/redis-check-rdb’
‘/usr/bin/redis-cli’ -> ‘/app/redis/bin/redis-cli’
‘/usr/bin/redis-sentinel’ -> ‘/app/redis/bin/redis-sentinel’
‘/usr/bin/redis-server’ -> ‘/app/redis/bin/redis-server’

1.2.2:连接到Redis

redis-cli     #本机非密码连接
进入之后使用AUTH passwd的方式    #本机密码连接       配置文件中设置requirepass passwd 
redis-cli -h HOSTNAME/IP -p PORT  跨主机非密码连接
redis-cli -h HOSTNAME/IP -p PORT -a PASSWORD  #跨主机密码连接

1.2.3:shell脚本写入数据到Redis

#!/bin/bash
NUM=`seq 1 100000`
for i in ${NUM};do
redis-cli -h 127.0.0.1 set key-${i} value-${i}
echo "key-${i} value-${i} 写入完成"
done
echo "十万个key写入到Redis完成

1.2.4:python连接方式

#!/bin/env python
import redis
import time
pool = redis.ConnectionPool(host="192.168.7.101", port=6379,password="")
r = redis.Redis(connection_pool=pool)
for i in range(100):
r.set("k%d" % i,"v%d" % i)
time.sleep(1)
data=r.get("k%d" % i)
print(data)

1.3:redis配置文件

1.3.1:redis主要配置项

命令行修改:CONFIG SET 

databases 16 #设置db 库数量,默认16个库,业务级别的分离,命令:SELECT num,python中db=num
pidfile /var/run/redis_6379.pid #pid文件路径
logfile "" #日志路径
save 900 1 #在900秒内有一个键内容发生更改就出就快照机制
rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之
rdbchecksum yes #是否开启RC64校验,默认是开启
dbfilename dump.rdb #快照文件名
dir ./ #快照文件保存路径
replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:
1、如果replica-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的读请求。
2、如果replica-serve-stale-data设置为no,除去指定的命令之外的任何请求都会返回一个错误"SYNC with master in progress"。在较慢并且网络较快的时候,可以用diskless(yes),否则使用磁盘(no)
repl-backlog-size 512mb #复制缓冲区内存大小,只有在slave连接之后才分配内。主从同步时使用,redis划分的不包含这内存
maxmemory #最大内存,单位为bytes字节,一般为总内存的一半。0为不限制
appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dumpd数据的间隔时间),根据save来策略进行持久化,
Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
lua-time-limit 5000 #lua脚本的最大执行时间,单位为毫秒
cluster-enabled yes #是否开启集群模式,默认是单机模式
cluster-config-file nodes-6379.conf #由node节点自动生成的集群配置文件
cluster-node-timeout 15000 #集群中node节点连接超时时间
cluster-replica-validity-factor 10 #在执行故障转移的时候可能有些节点和master断开一段时间数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移
cluster-migration-barrier 1 #集群迁移屏障,一个主节点拥有的至少正常工作的从节点,即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。
cluster-require-full-coverage no #集群请求槽位全部覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么yes情况下redis集群槽位验证不全就不再对外提供服务,而no则可以继续使用但是会出现查询数据查不到的情况(因为有数据丢失)。
#Slow log 是 Redis 用来记录查询执行时间的日志系统,slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。

慢日志:
slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。
slowlog-max-len 128 #记录多少条慢日志保存在队列,超出后会删除最早的,以此滚动删除


127.0.0.1:6379> slowlog get   #获取slowlog
1) 1) (integer) 6
   2) (integer) 1581479461
   3) (integer) 98
   4) 1) "set"
      2) "key1"
      3) "v1"

127.0.0.1:6379> slowlog reset   #清空slowlog
OK
127.0.0.1:6379> slowlog len
(integer) 1

1.4:redis 数据类型

http://www.redis.cn/topics/data-types.html

1.4.1.1:单个字符串(string)操作

127.0.0.1:6379> set key-1 value_1 #添加
OK
127.0.0.1:6379> get key-1 #获取
"value_1"
127.0.0.1:6379> type key-1 #查看类型
string
127.0.0.1:6379> del key-1 #删除
(integer) 1

1.4.1.2:批量设置多个key

127.0.0.1:6379> mset key-1 value-1 key_2 value-2
OK
127.0.0.1:6379> mget key-1 key_2
1) "value-1"
2) "value-2"

1.4.1.3:追加数据

127.0.0.1:6379> get key-1
"value-1"
127.0.0.1:6379> append key-1 append  #在原来的字符上添加
(integer) 13
127.0.0.1:6379> get key-1
"value-1append"

1.4.1.4:数值递增、递减

127.0.0.1:6379> set num 0
OK
127.0.0.1:6379> get num
"0"
127.0.0.1:6379> incr num  #数值递增
(integer) 1
127.0.0.1:6379> get num
"1"
127.0.0.1:6379> decr num #数值递减
(integer) 0
127.0.0.1:6379> get num
"0"

1.4.1.5:key相关操作

127.0.0.1:6379> STRLEN key-1   #返回字符串key长度
(integer) 13
127.0.0.1:6379> EXISTS key-1    #判断key是否存在
(integer) 1
127.0.0.1:6379> EXISTS key1      #不存在返回值为0
(integer) 0
127.0.0.1:6379> TTL key-1           #查看key的过期时间
(integer) -1
127.0.0.1:6379> TTL key1
(integer) -2
ttl #查看key的剩余生存时间
-1 #负一为永不过期,默认创建的key是永不过期,重新对key赋值,也会从有剩余生命周期变成永不过期
-2 #为没有此key
num #key的剩余有效期

127.0.0.1:6379> EXPIRE key-1 86400    #设置key的过期时间
(integer) 1
127.0.0.1:6379> PERSIST key-1          #取消key的过期时间
(integer) 1

1.4.2:列表(list)

列表是一个双向可读写的管道,其头部是左侧尾部是右侧,一个列表最多可以包含2^32-1个元素即4294967295个元素。
原则:数据先进先出;LPUSH—左侧插入数据;RPUSH—右侧插入数据;LPOP—从左侧取数据;RPOP—从右侧取数据

1.4.2.1:与列表相关的操作

127.0.0.1:6379> LPUSH list1 jack tom jhon #根据顺序逐个写入list1,最后的jhon会在列表的最左侧。
(integer) 3
127.0.0.1:6379> TYPE list1
list
127.0.0.1:6379> LPUSH list1 lou  #向列表追加数据
(integer) 4
127.0.0.1:6379> LLEN list1  #获取列表长度
(integer) 4
127.0.0.1:6379> LRANGE list1 1 2 #指定范围
1) "jhon"
2) "tom"
127.0.0.1:6379> RPOP list1  #移除列表数据最后一个
"jack"
127.0.0.1:6379>  LLEN list1
(integer) 3
127.0.0.1:6379> LPOP list1  #移除列表数据第一个
"lou"

1.4.3:集合(set)

 Set 是 String 类型的无序集合,集合中的成员是唯一的,这就意味着集合中不能出现重复的数据,可以在两个不同的集合中对数据进行对比并取值。

1.4.3.1:

127.0.0.1:6379> SADD set1 v1  #生成集合key
(integer) 1
127.0.0.1:6379> type v1
none
127.0.0.1:6379> type set1
set
127.0.0.1:6379> SADD set2 v2 v4  #追加数值
(integer) 2
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> SADD set1 v2 v3 v4
(integer) 3
127.0.0.1:6379> SMEMBERS set1   #查看集合的所有数据
1) "v2"
2) "v4"
3) "v1"
4) "v3"
127.0.0.1:6379> SDIFF set1 set2  #差集:已属于A而不属于B的元素称为A与B的差(集)
1) "v1"
2) "v3"
127.0.0.1:6379> SINTER set1 set2    #交集:已属于A且属于B的元素称为A与B的交(集)
1) "v2"
2) "v4"
127.0.0.1:6379> SUNION set1 set2 #并集:已属于A或属于B的元素为称为A与B的并(集)
1) "v1"
2) "v4"
3) "v3"
4) "v2"
127.0.0.1:6379> SUNION set1 set2
1) "v1"
2) "v4"
3) "v3"
4) "v2"

1.4.4:哈希(hash)

hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象,Redis 中每个 hash 可以存储 2^32 -1 键值对(40多亿)。

127.0.0.1:6379> HSET hash1 name tom age 18  #生成hash key
(integer) 2
127.0.0.1:6379> TYPE hash1
hash
127.0.0.1:6379> HGET hash1 name #获取hash key字段值
"tom"
127.0.0.1:6379> HGET hash1 age
"18"
127.0.0.1:6379> HDEL hash1 age  #删除一个hash key的字段
(integer) 1
127.0.0.1:6379> HMSET hash1 name tom age 19    #获取所有hash表中的key
OK
127.0.0.1:6379> HKEYS hash1
1) "name"
2) "age"
127.0.0.1:6379> HGETALL hash1     #获取指定hash的所有key及value
1) "name"
2) "tom"
3) "age"
4) "19"