Python搭建Redis集群
文章图片
官网:https://redis.io/ 总结Ubuntu搭建流程:
# 安装redis
sudo apt install redis-server
redis-server -v
redis-cli -v
# 安装ruby
sudo apt-get install ruby rubygems
ruby -v
gem -v
# 安装ruby插件
sudo gem install redis -v 3.0.6 (根据redis版本决定)# 复制3份redis.conf,分别在3台机器上(或者1台机器上的不同文件夹)启动redis-server实例
redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf
# 创建集群
redis-trib.rb create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381# 如果是不同机器需要替换成各个机器的IP
1 什么是Redis
- REmote DIctionary Server(Redis)
- 是一个由Salvatore Sanfilippo写的key-value存储系统。
- 基于内存(也可以基于持久化)存储
- 通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
- 读写性能高:读的速度是110000次/s,写的速度是81000次/s
- 数据类型丰富:支持 Strings, Lists, Hashes, Sets 及 Ordered Sets
- 原子性操作:所有的操作要么成功执行要么失败完全不执行
- 轻量化:整个软件才2M,内存占用极少
- 单机多实例,同机器可以给多个应用配置多个Redis数据库,因为资源占用极少
- 存储在内存中(几乎是计算机存储的最高读写速度),又支持备份到磁盘中
- 相比较其他的NoSQL数据库(非关系型数据库):
【优点】利用多核优势,吞吐可以达到几十万QPS(日常5-6w QPS)。
【缺点】但只支持简单的key/value数据结构(不像Redis可以支持丰富的数据类型),不能持久化,不能备份,重启后数据消失,内存采用Slab Allocation机制管理,value大小分布差异大的时候内存利用率低。
(2)Redis:
【优点】支持多种数据结构,支持持久化到磁盘来进行数据备份或恢复,支持通过master-slave机制做数据复制,单线程串行执行所有命令,不需要考虑数据一致性。支持pub/sub消息订阅机制。
【缺点】只能使用单线程,性能受限于CPU性能,单实例CPU最高只能达到5-6wQPS(日常1-2w QPS),在string类型上会消耗比较多的内存,可以使用dict(hash表)压缩存储来降低内存耗用
(3)MoongoDB:
【优点】有更高的写入速度,处理大规模单表可以很容易的分割表
【缺点】占用空间过大,没有成熟的维护工具,不支持事务
- 三者区别:
① 简单存取key-value用memcached好一些,多数据类型用Redis,数据量比较大用MongoDB。
② memcached客户端更成熟稳定,Redis协议比Memcached复杂,但Redis实际测试表现比mencached好。
③ 大家习惯称 『Redis缓存』『MongoDB数据库』。
④MongoDB更多采用集群部署,Redis偏向于进程顺序写入,集群部署也仅限于主-从模式。
Linux安装:
sudo apt install redis-server
Mac安装:
brew install redis
Docker安装:不太推荐,因为Redis实在是太轻量了
下载编译安装:目前最新稳定版本为6.0.8
wget http://download.redis.io/releases/redis-6.0.8.tar.gz
tar xzf redis-*.tar.gz
cd redis-*make
make test
sudo make install# 执行完 make 命令后,redis-6.0.8 的 src 目录下会出现编译后的 redis 服务程序 redis-server,还有用于测试的客户端程序 redis-cli
cd src
ls redis-server redis-cli
3.2 配置文件 只有一个redis.conf文件(经常需要修改的配置如下)
# 绑定主机IP和PORT,端口是redis默认的
bind 0.0.0.0
port 6379# (推荐)守护进程运行方式开启,这样不会进入命令行"前台堵塞模式"
daemonize yes# pid文件
pidfile /var/run/redis_6379.pid
# 日志文件保存位置
logfile "/usr/local/redis/cluster/6379/redis.log"
# 数据文件
dbfilename dump.db
# 数据存储目录设置,运行前需要手动创建文件夹,否则报错
dir "/usr/local/redis/cluster/6379"# 数据库数量,默认16个数据库
database 16# 是否从机
slaveof IP:PORT
#数据是否持久化
appendonly yes# 集群配置
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
3.3 启动和关闭
# 服务端启动与关闭
cdredis-*/src
./redis-server# 或者指定配置文件启动
./redis-server redis.conf# 关闭,可以直接在原窗口Ctrl+C,或者另外起一个终端,用客户端命令关闭服务端
./redis-cli shutdown
- 检查是否启动:
ps aux | grep redis
- 如果要开机启动,在
/etc/rc.local
中加入启动redis的命令即可,但这样还不如设置系统的service好管理。
# 进入客户端shell
cdredis-*/src
./redis-cli127.0.0.1:6379> ping# 如果输出 Output 说明通信成功
127.0.0.1:6379> set test "It's working !"# 如果输出 OK 说明写入成功
127.0.0.1:6379> get test# 如果输出 "It's working !" 说明读取成功# 关闭客户端
127.0.0.1:6379> exit
如果想检查redis是否有把数据持久化备份到磁盘,可以重启redis然后再进入客户端去获取之前存入的Key。
3.4 卸载Redis(注意先关闭redis相关服务)
- mac:
brew uninstall redis
- Linux:
sudo apt-get purge --auto-remove redis-server
- 本地编译方式,卸载redis服务,只需把/usr/local/bin/目录下的redis相关文件删除即可,为了卸载干净,你还可以把解压和编译的redis包以及相关的配置和日志目录也给删除了(取决于配置的对应目录)。
rm /usr/local/bin/redis-*# redis程序文件
rm -r /etc/redis/# 配置目录和内容
rm /var/log/redis_*# 日志
rm -r /var/lib/redis/# 数据目录和内容
rm /etc/init.d/redis_*# 初始化脚本
rm /var/run/redis_*# 现有的Redis PID文件
4 单机模式 4.1 启动
redis-server
4.2 Python操作客户端 From:https://github.com/andymccurdy/redis-py
安装redis库:
pip install redis
>>> import redis
>>> r = redis.Redis(host='localhost', port=6379, db=0)
>>> r.set('foo', 'bar')
True
>>> r.get('foo')
b'bar'
5 集群模式 5.1 主从方式启动 Master-Slave架构,实际上只是一种备份关系,只能从Master写,可以分别从Master和Slave读。
文章图片
master-slave
- Step1:主从机器上都安装了
redis-server
- Step2:主从机器上都有配置文件redis.conf,并分别配置主机和从机。
master-6379-redis.conf
修改bind 0.0.0.0
port 6379
logfile "6379.log"
dbfilename "dump-6379.rdb"
daemonize yes# 后台运行
rdbcompression yes # 压缩数据
appendonly no # 不持久化
从节点配置文件
slave-6380-redis.conf
修改(如果在同一台机器上则要修改端口号)bind 0.0.0.0
port 6380
logfile "6380.log"
dbfilename "dump-6380.rdb"
daemonize yes
rdbcompression yes
slaveof 127.0.0.1:6379
- Step3:分别启动
redis-server *-redis.conf
- Step4:测试主从模式,客户端连接master节点,set数据,再分别连接slave节点,get数据。详细参考
- 集群架构:将数据分为16,384个槽(Slot),平均分给每台机器,通过Redirection转发数据给对应的槽,使用Hash Table确定数据存在哪个槽
- 集群分区Partition:在有些机器不可用、离线的时候,集群也可以继续完成请求任务。
- 启动方式
复制3份redis.conf,修改三处地方(如果是不同机器可以不用修改端口)
# 主节点
port 6379
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
每台机器(节点)启动1个实例
./redis-server ./redis-6379.conf
使用Ruby(Redis集群管理工具),通过Cluster相关命令帮用户简化集群创建、检查、槽迁移和均衡等常见的运维操作,使用之前需要安装Ruby(因为我们要使用redis-trib.rb帮助我们进行简单集群配置比如分配槽位,但redis-trib.rb是由ruby语言编写的所以需要安装ruby环境。)
# 安装ruby
# 方法1:Ubuntu 安装
sudo apt-get install ruby rubygems
# Ubuntu 卸载
gem uninstall rails
sudo apt-get purge ruby
sudo apt-get remove ruby rubygems# 方法2:源码安装
(官网:http://www.ruby-lang.org/en/downloads/)最新稳定版本是2.7.2
wget https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.gz
tar -zxf ruby-*.tar.gz
cd ruby-*
./configure --prefix=/usr/local/ruby
sudo make && make install
sudo vim /etc/profile # 加入环境变量
PATH=/usr/local/ruby/bin:$PATH
source /etc/profile
ruby安装完成后:
# 可以使用Ruby安装Redis插件
sudo gem install redis -v 3.0.6
接下来要用redis-trib.rb工具来构建集群,如果是编译安装redis,这个工具就在编译后的src目录下,如果是apt安装,找不到这个文件,可以通过github下载,注意redis必须是3.0.6及以后的。下载后chmod加执行x权限。
# 使用ruby把3个实例创建起集群,中途日志会告知16364个槽位的分配情况,输入yes确认即可
./redis-trib.rb create IP1:6379IP2:6379 IP3:6379
# 构建完成, 集群完整性检查
./redis-trib.rb check 127.0.0.1:6379
5.3 Python操作客户端 From:https://github.com/Grokzen/redis-py-cluster
安装库:
pip install redis-py-cluster
存正常的字符串
from rediscluster import StrictRedisClusterstartup_nodes = [{"host": "100.90.243.35", "port": "8400"},
{"host": "100.90.243.36", "port": "8400"},
{"host": "100.90.243.39", "port": "8400"}
]# 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"))
存numpy的array
from rediscluster import StrictRedisCluster
from tqdm import tqdm
import numpy as np
import msgpack
import msgpack_numpy as m
m.patch()class RedisCluster(object):
def __init__(self):
startup_nodes = [{"host": "100.90.243.35", "port": "8400"},
{"host": "100.90.243.36", "port": "8400"},
{"host": "100.90.243.39", "port": "8400"}
]
self.rc = StrictRedisCluster(startup_nodes=startup_nodes)def set(self, task_name, itr, params):
key = str(task_name) + str(itr)
val = np.asarray(params)
val = m.packb(val)
return self.rc.set(key, val)def get(self, task_name, itr):
key = str(task_name) + str(itr)
out = self.rc.get(key)
# print("TTTTTTTTTTTTTTTTT", type(out))
out = m.unpackb(out)
return outif __name__ == '__main__':
# numpy data
d_data = https://www.it610.com/article/np.array([[8.,2.],[3.,4.]])
print('d_data', d_data.shape, type(d_data), d_data)rc = RedisCluster()
success = rc.set('mytask', 10, d_data)d_out = rc.get('mytask', 10)print('d_out', d_out.shape, type(d_out), d_out)
参考 https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04
https://blog.csdn.net/liqingtx/article/details/60330555
踩坑 1. 运行Python脚本报错
- 报错from rediscluster import StrictRedisCluster, importerror cannot import name 'strictrediscluster'
原因是python库版本默认是最新的,而redis的版本可能比较老。可以降版本尝试,博主的redis版本是3.0.6,redis==2.10.6
,redis-py-cluster==1.3.5
ResponseError: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.(Redis无法向磁盘写入RDB的报错)
原因是
appendonly no
强制把redis快照关闭了导致不能持久化的问题,解决方案:- 通过在配置文件中设置
stop-writes-on-bgsave-error no
(记得重启redis服务)即可避免这种问题。 - 如果不想重启redis服务,可以通过client设置
127.0.0.1:6379> config set stop-writes-on-bgsave-error no
3. 安装redis过程中报错
网上搜对应策略
make MALLOC=libc
taskset -c 1 sudo make test
推荐阅读
- python学习之|python学习之 实现QQ自动发送消息
- 逻辑回归的理解与python示例
- 六步搭建ES6语法环境
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- Python基础|Python基础 - 练习1
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- Python(pathlib模块)
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- Python数据分析(一)(Matplotlib使用)