redis(1)
一、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/
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
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
成功启动
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启动
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"