一、Redis介绍
什么是redis?一个专门做数据缓存的软件,将数据在服务器的内存上进行存储,提高数据的查询的效率。与memcache不同的是,redis将数据保存在内存中的同时,会定期将数据也会写到文件中,避免服务器关机等时数据消失。电脑开机的会将数据重新新放在内存上。总结如下:
''' 1、用途: 做缓存和做消息队列 2、本质: 将数据存放在内存中 3、特性: 可做持久化 支持存放5种数据格式,如下: ''' {"k1":"xxxx" #字符串 "k2":[11,22,33] #列表 "k3":{11,22,33} #集合 "k4":{"k1":"v1","k2":"v2"} #哈希散列表 "k5":{("egon",1),("alex",2)} #有序集合 }
1、redis特性
2、redis与memcache比较
''' 在单用户多并发读写,redis性能高 在多用户少读写时,memcache更优 ''' #总结:redis是一个单核的管理机制,生产中一般是,单机多实例的架构。
3、redis配置文件示例
#进入配置文件:vim /etc/redis.conf ''' daemonize no/yes 是否后台运行 port 6379 默认端口 appendonly no/yes AOF日志开关是否打开 logfile /var/log/redis.log 日志文件位置 dbfilename dump.rdb RDB持久化数据文件 '''
4、直接在命令行调用redis命令配置
#配置方式: ''' cd /root vim .bash_profile PATH 行添加 :/application/redis-3.2.6/src 保存后执行: source .bash_profile ''' #使用实例: ''' redis-cli 开启客户端 shutdown 关闭客户端 redis-server /etc/redis.conf 启动服务 '''
5、安全控制配置
通过如下配置,限制连接的用户。
#打开配置文件:vim /etc/redis.conf ''' 配置实例: bind 10.0.0.200 限制ip requirepass root 设置密码 '''
按照如上方式配置后打开方式实例:
''' 启动redis redis-server /etc/redis.conf 连接redis: redis-cli -h 10.0.0.200 -a root ''' # -h <hostname> # -p <port> # -a <password> #说明: ''' redis-cli 默认情况是以下的方式连接redis-cli -h 127.0.0.1 -p 6379 '''
6、在线更改配置
在线修改的配置,下次登录生效,但是重启之后配置会丢失。
''' 获取当前配置: CONFIG GET * 变更运行配置: 例子:修改密码 CONFIG SET requirepass "123" 查看配置结果: CONFIG GET requirepass '''
二、redis持久化
因为Redis是内存型数据库,所以为了防止因为系统崩溃等原因导致数据丢失的问题,Redis提供了两种不同的持久化方法来将数据存储在硬盘里面,一种方法是快照(RDB),它可以将存在于某一个时刻的所有数据都写入到硬盘里面,另外一种方法是只追加文件(AOF),它会在执行写命令时,将被执行的写命令都写入到硬盘里面。
1、快照持久化
Redis可以通过创建快照来获得在内存里面的数据在某一个时间点上的副本。在创建快照之后,用户可以对快照进行备份,可以将快照复制到其它服务器从而创建具有相同数据的服务器副本,还可以将快照留在原地以便重启服务器时使用。在只使用快照持久化来保存数据时,如果系统真的发生崩溃,用户将丢失最近一次生成快照之后更改的所有数据。因此,快照持久化只适用于那些即使丢失一部分数据也不会造成问题的应用程序。
#配置示例 ''' dbfilename dump.rdb dir "/application/data/6379" save 900 1 #900秒(15分钟)内有1个更改 save 300 10 #300秒(5分钟)内有10个更改 save 60 10000 #60秒内有10000个更改 '''
2、文件持久化
AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来纪录数据所发生的变化,因此,Redis只要从头到尾重新执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件所记录的数据集。因为Redis会不断的将被执行的写命令纪录到AOF文件里面,所以随着Redis不断执行,AOF文件的体积也会不断增长,极端条件下,AOF甚至可能会用完硬盘的所有可用空间。为了解决上面的缺点,Redis提供了BGREWRITEAOF命令,这个命令会通过移除AOF文件中的冗余命令来重写AOF文件,使得AOF文件尽可能的小。它的原理和BGSAVE命令相似,Redis会创建一个子进程,然后由子进程负责对AOF文件进行重写,因为AOF文件重写也需要用到子进程,所以同样存在快照持久化因为创建子进程所导致的性能问题和内存占用问题。
#配置示例: ''' appendonly yes appendfsync everysec #共有三种方式 '''
三、发布订阅
''' SUBSCRIBE weibo 订阅一个频道 PSUBSCRIBE * 订阅多个频道 PSUBSCRIBE beijing.* 订阅所有和北京相关的频道 ''' 使用实例:(发布消息后,订阅的就会收到) PUBLISH weibo hello
四、主从复制
主从复制有故障转移 (failover)和分担负载 (balance),实现高可用。
1、传统主从复制
配置说明:
准备2个以上的redis实例,准备多配置文件(端口、数据路径、日志路径、pid): ''' 端口: 6380(主) 6381(从) 数据路径(持久化文件存放位置): /application/data/6380 /application/data/6381 日志路径: /var/log/redis6380.log /var/log/redis6381.log pid文件 /application/data/6380/redis.pid /application/data/6381/redis.pid '''
配置过程:
''' 1、创建目录 mkdir -p /application/data/6380 mkdir -p /application/data/6381 2、配置文件 vim /application/data/6380/redis.conf port 6380 daemonize yes pidfile /application/data/6380/redis.pid logfile "/var/log/redis6380.log" dbfilename dump.rdb dir /application/data/6380 vim /application/data/6381/redis.conf port 6381 daemonize yes pidfile /application/data/6381/redis.pid logfile "/var/log/redis6381.log" dbfilename dump.rdb dir /application/data/6381 3、启动两个实例 redis-server /application/data/6380/redis.conf redis-server /application/data/6381/redis.conf 4、构建主从 redis-cli -p 6381 slaveof 127.0.0.1 6380 5、验证主从 登录主库: redis-cli -p 6380 set foo bar 登录从库: redis-cli -p 6381 get foo 6、主从复制状态查看。 role info replication 7、主从复制,手工切换 slaveof no one '''
2、sentinel主从复制
传统主从复制有如下缺陷:没有自动监控机制、没有自动切换的功能、对于应用不透明;解决办法就是sentinel主从复制,具有如下功能:自动监控redis所有节点状态;发现主库故障,自动选主切换;自动通知应用端。
配置说明:
#准备,1主2从结构比较合适,所以继续添加6382节点: ''' mkdir -p /application/data/6382 vim /application/data/6382/redis.conf port 6382 daemonize yes pidfile /application/data/6382/redis.pid logfile "/var/log/redis6382.log" dbfilename dump.rdb dir /application/data/6382 redis-server /application/data/6382/redis.conf redis-cli -p 6382 slaveof 127.0.0.1 6380 '''
配置过程:
''' 配置: mkdir -p /application/data/26380 vim /application/data/26380/sentinel.conf port 26380 dir "/application/data/26380" sentinel monitor mymaster 127.0.0.1 6380 1 sentinel down-after-milliseconds mymaster 60000 sentinel config-epoch mymaster 0 启动: redis-sentinel /application/data/26380/sentinel.conf '''
python使用示例:
from redis.sentinel import Sentinel sentinel = Sentinel([('127.0.0.1', 26380)], socket_timeout=0.1) sentinel.discover_master('mymaster') #查看主节点,mymaster是名字,配置中设置 sentinel.discover_slaves('mymaster') #查看子节点 master = sentinel.master_for('mymaster', socket_timeout=0.1) #获取主节点 slave = sentinel.slave_for('mymaster', socket_timeout=0.1) #获取子节点 #使用实例: master.set('foo', 'bar') slave.get('foo')
五、分布式集群
主要解决高并发问题。
1、分布式集群部署
''' 1、集群组件安装 EPEL源安装ruby支持 yum install ruby rubygems -y 使用国内源 gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/ 如果无法使用,可以使用aliyun gem sources -a http://mirrors.aliyun.com/rubygems/ gem sources --remove http://rubygems.org/ gem sources -l gem install redis -v 3.3.3 2、集群节点准备 (1)规划: 端口: 7000-7005 路径: /application/data/7000 /application/data/7001 /application/data/7002 /application/data/7003 /application/data/7004 /application/data/7005 日志路径: /var/log/redis7000.log /var/log/redis7001.log /var/log/redis7002.log /var/log/redis7003.log /var/log/redis7004.log /var/log/redis7005.log pid文件路径: /application/data/7000/redis.pid /application/data/7001/redis.pid /application/data/7002/redis.pid /application/data/7003/redis.pid /application/data/7004/redis.pid /application/data/7005/redis.pid (2)创建节点目录: mkdir -p /application/data/7000 mkdir -p /application/data/7001 mkdir -p /application/data/7002 mkdir -p /application/data/7003 mkdir -p /application/data/7004 mkdir -p /application/data/7005 (3)配置文件添加: vim /application/data/7000/redis.conf port 7000 daemonize yes pidfile /application/data/7000/redis.pid logfile "/var/log/redis7000.log" dbfilename dump.rdb dir /application/data/7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes vim /application/data/7001/redis.conf port 7001 daemonize yes pidfile /application/data/7001/redis.pid logfile "/var/log/redis7001.log" dbfilename dump.rdb dir /application/data/7001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes vim /application/data/7002/redis.conf port 7002 daemonize yes pidfile /application/data/7002/redis.pid logfile "/var/log/redis7002.log" dbfilename dump.rdb dir /application/data/7002 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes vim /application/data/7003/redis.conf port 7003 daemonize yes pidfile /application/data/7003/redis.pid logfile "/var/log/redis7003.log" dbfilename dump.rdb dir /application/data/7003 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes vim /application/data/7004/redis.conf port 7004 daemonize yes pidfile /application/data/7004/redis.pid logfile "/var/log/redis7004.log" dbfilename dump.rdb dir /application/data/7004 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes vim /application/data/7005/redis.conf port 7005 daemonize yes pidfile /application/data/7005/redis.pid logfile "/var/log/redis7005.log" dbfilename dump.rdb dir /application/data/7005 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes (4)启动所有节点: redis-server /application/data/7000/redis.conf redis-server /application/data/7001/redis.conf redis-server /application/data/7002/redis.conf redis-server /application/data/7003/redis.conf redis-server /application/data/7004/redis.conf redis-server /application/data/7005/redis.conf ps -ef |grep 700 #查看是否启动 3、集群创建 redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
4、集群状态查看 redis-cli -p 7000 cluster nodes | grep master '''
2、python使用介绍
''' (1) redis-py并没有提供redis-cluster的支持,去github找了一下,有个叫redis-py-cluster的源码, 但是和redis-py不是一个作者,地址为:https://github.com/Grokzen/redis-py-cluster (2) 安装 Latest stable release from pypi $ pip install redis-py-cluster or from source $ python setup.py install (3) 使用 from rediscluster import StrictRedisCluster startup_nodes = [{"host": "127.0.0.1", "port": "7000"}] # Note: decode_responses must be set to True when used with python3 rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True) rc.set("foo", "bar") print(rc.get("foo")) #'bar' '''
六、redis-py连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
1、方式一
利用redis中的ConnectionPool创建连接池,然后各视图中使用此连接池,实例如下:
#pool.py文件 import redis POOL = redis.ConnectionPool(host='47.93.4.198',port=6379) #views.py文件 from django.shortcuts import render import redis from pool import POOL def index(request): conn = redis.Redis(connection_pool=POOL) .... def home(request): conn = redis.Redis(connection_pool=POOL) ....
2、方式二
利用django-redis组件实现连接池,安装django-redis组件方式为:pip3 install django-redis ,使用实例如下:
配置文件:
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://47.93.4.198:6379", #服务器ip "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": "", #有密码就设置 } } }
使用实例:
import django_redis conn = django_redis.get_redis_connection()
七、memcache
详细内容参考博客:http://www.cnblogs.com/wupeiqi/articles/5132791.html