Codis 简介

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有显著区别 (有一些命令不支持), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。

Codis的github:https://github.com/CodisLabs/codis

Codis特性如下

  • 最新 release 版本为 codis-3.2,codis-server 基于 redis-3.2.8
  • 支持 slot 同步迁移、异步迁移和并发迁移,对 key 大小无任何限制,迁移性能大幅度提升
  • 相比0:重构了整个集群组件通信方式,codis-proxy 与 zookeeper 实现了解耦,废弃了codis-config 等
  • 元数据存储支持 etcd/zookeeper/filesystem 等,可自行扩展支持新的存储,集群正常运行期间,即便元存储故障也不再影响 codis 集群,大大提升 codis-proxy 稳定性
  • 对 codis-proxy 进行了大量性能优化,通过控制GC频率、减少对象创建、内存预分配、引入 cgo、jemalloc 等,使其吞吐还是延迟,都已达到 codis 项目中最佳
  • proxy 实现 select 命令,支持多 DB
  • proxy 支持读写分离、优先读同 IP/同 DC 下副本功能
  • 基于 redis-sentinel 实现主备自动切换
  • 实现动态 pipeline 缓存区(减少内存分配以及所引起的 GC 问题)
  • proxy 支持通过 HTTP 请求实时获取 runtime metrics,便于监控、运维
  • 支持通过 influxdb 和 statsd 采集 proxy metrics
  • slot auto rebalance 算法从0 的基于 max memory policy 变更成基于 group 下 slot 数量
  • 提供了更加友好的 dashboard 和 fe 界面,新增了很多按钮、跳转链接、错误状态等,有利于快速发现、处理集群故障
  • 新增 SLOTSSCAN 指令,便于获取集群各个 slot 下的所有 key
  • codis-proxy 与 codis-dashbaord 支持 docker 部署

codis架构如下

codis 组件介绍

codis server:基于redis-3.2.8 分支开发。增加了额外的数据结构,以支持slot有关的操作以及数据迁移指令。具体的修改可以参考文档redis的修改

codis proxy:客户端连接的redis代理服务,实现了redis协议。除部分命令不支持以外(不支持的命令列表),表现的和原生的redis没有区别。

对于同一个业务集群而言,可以同时部署多个codis-proxy实例;

不同codis-proxy之间由codis-dashboard保证状态同步。

codis dashboard:集群管理工具,支持codis-proxy、codis-server的添加、删除、以及数据迁移操作。在集群状态发生改变时,codis-dashboard维护集群下所有codis-proxy的状态一致性。

对于同一个业务集群而言,同一时刻codis-dashboard只能有0个或者1个

所有对集群的修改都必须通过codis-dashboard完成。

codis FE:集群管理界面

多个集群实例共享可以共享同一个前端展示页面;

通过配置文件管理后端codis-dashboard列表,配置文件可自动更新。

storage

提供namespace概念,不同集群会按照不同product name进行组织;

目前仅提供了zookeeper、etcd、fs三种实现,但是提供了抽象的interface可自行扩展。

codis 是如何分片的

Codis 采用 Pre-sharding 的技术来实现数据的分片, 默认分成 1024 个 slots (0-1023), 对于每个key来说, 通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024。

每一个 slot 都会有一个且必须有一个特定的 server group id 来表示这个 slot 的数据由哪个 server group 来提供。数据的迁移也是以slot为单位的。

Codis部署

环境说明

节点编号IP地址操作系统node1192.168.28.71Centos 7.2node2192.168.28.72Centos 7.2node3192.168.28.73Centos 7.2

Codis部署架构如下图

codis server主从分布如下图

安装部署

zookeeper 安装

codis的元数据存储依赖zookeeper,所以在安装codis之前我们需要安装一个zookeeper环境

安装过程略

go安装

由于codis是go语言写的,所以需要在每台codis主机安装go语言运行环境。

1、安装go

[root@node1 ~]# yum -y install golang

2、设置go运行环境

[root@node1 ~]# mkdir /data/go -p[root@node1 ~]# vim /etc/profileexport GOPATH=/data/goexport PATH=$PATH:$GOPATH/bin[root@node1 ~]# source /etc/profile

3、安装godep

[root@node1 ~]# yum -y install git[root@node1 ~]# go get -u github.com/tools/godep && which godep/data/go/bin/godep

codis 安装

1、安装依赖

yum install autoconf automake libtool -y

2、编译安装

mkdir -p /data/go/src/github.com/CodisLabscd /data/go/src/github.com/CodisLabsgit clone https://github.com/CodisLabs/codis.git -b release3.2cd codis/make

3、配置文件修改dashboard 配置修改

# vim config/dashboard.tomlcoordinator_name = "zookeeper"coordinator_addr = "192.168.28.71:2181,192.168.28.72:2181,192.168.28.73:2181"product_name = "xuele-codis"

复制配置文件到另外两个节点

scp config/dashboard.toml 10.1.13.172:/data/go/src/github.com/CodisLabs/codis/config/dashboard.toml
scp config/dashboard.toml 10.1.13.173:/data/go/src/github.com/CodisLabs/codis/config/dashboard.toml

4、codis-proxy配置

# vim config/proxy.tomlproduct_name = "xuele-codis"product_auth = ""jodis_name = "zookeeper"jodis_addr = "192.168.28.71:2181,192.168.28.72:2181,192.168.28.73:2181"jodis_auth = ""jodis_timeout = "20s"jodis_compatible = true

复制配置文件到另外两个节点

scp config/proxy.toml 10.1.13.172:/data/go/src/github.com/CodisLabs/codis/config/proxy.tomlscp config/proxy.toml 10.1.13.173:/data/go/src/github.com/CodisLabs/codis/config/proxy.toml

5、codis-server配置

[root@c7-node1 redis-3.2.11]# pwd/data/go/src/github.com/CodisLabs/codis/extern/redis-3.2.11[root@c7-node1 redis-3.2.11]# mkdir /data/redis[root@c7-node1 redis-3.2.11]# cp redis.conf /data/redis/redis-6379.conf[root@c7-node1 redis-3.2.11]# cp redis.conf /data/redis/redis-6380.conf[root@c7-node1 redis-3.2.11]# cp redis.conf /data/redis/redis-6381.conf

6、redis配置文件修改

# vim /data/redis/redis-6379.confport 6379pidfile /tmp/redis_6379.pidlogfile "/tmp/redis_6379.log"dbfilename dump_6379.rdbmaxmemory 1gdir /data/redis/redis_6379修改6379为6380
# vim /data/redis/redis-6380.confport 6380pidfile /tmp/redis_6380.pidlogfile "/tmp/redis_6380.log"dbfilename dump_6380.rdbmaxmemory 1gdir /data/redis/redis_6380

修改6379为6381

# vim /data/redis/redis-6381.confport 6381pidfile /tmp/redis_6381.pidlogfile "/tmp/redis_6381.log"dbfilename dump_6381.rdbmaxmemory 1gdir /data/redis/redis_6381

复制配置文件到另外两个节点

scp /data/redis/*.conf 10.1.13.172:/data/redis/scp /data/redis/*.conf 10.1.13.173:/data/redis/

修改完配置文件,还需要创建相关目录

mkdir /data/redis/redis_6379 -pmkdir /data/redis/redis_6380 -pmkdir /data/redis/redis_6381 -p

7、服务启动及初始化集群启动dashboard

# nohup ./bin/codis-dashboard --ncpu=1 --config=config/dashboard.toml --log=dashboard.log --log-level=WARN >> /var/log/codis_dashboard.log &

启动proxy

nohup ./bin/codis-proxy --ncpu=1 --config=config/proxy.toml --log=proxy.log --log-level=WARN >> /var/log/codis_proxy.log &

启动codis server

nohup ./bin/codis-server /data/redis/redis-6379.conf &nohup ./bin/codis-server /data/redis/redis-6380.conf &nohup ./bin/codis-server /data/redis/redis-6381.conf &

启动codis-fe

nohup ./bin/codis-fe --ncpu=1 --log=fe.log --log-level=WARN --zookeeper=192.168.28.71:2181,192.168.28.72:2181,192.168.28.73:2181 --listen=192.168.28.71:8090 &

访问codis管理界面

web界面配置

1、添加proxy

2、添加group和server

3、通过fe初始化solt

新增的集群 slot 状态是 offline,因此我们需要对它进行初始化(将 1024 个 slot 分配到各个 group),而初始化最快的方法可通过 fe 提供的 rebalance all slots 按钮来做,如下图所示,点击此按钮,我们即快速完成了一个集群的搭建。

测试验证

通过连接codis-proxy进行验证

# redis-cli -h 192.168.28.71 -p 19000192.168.28.71:19000> INFO# Serverredis_version:3.2.11redis_git_sha1:7191a280redis_git_dirty:0redis_build_id:a9271caacf948e7redis_mode:standaloneos:Linux 3.10.0-514.el7.x86_64 x86_64arch_bits:64multiplexing_api:epollgcc_version:4.8.5process_id:48993run_id:2f8dff0622b212a2838f232abf8a166c0f0efb25tcp_port:6379uptime_in_seconds:1369uptime_in_days:0hz:10lru_clock:7144691executable:/data/go/src/github.com/CodisLabs/codis/./bin/codis-serverconfig_file:/data/redis/redis-6379.conf # Clientsconnected_clients:49client_longest_output_list:0client_biggest_input_buf:0blocked_clients:0 # Memoryused_memory:5338840used_memory_human:5.09Mused_memory_rss:13819904used_memory_rss_human:13.18Mused_memory_peak:6361912used_memory_peak_human:6.07Mtotal_system_memory:1912107008total_system_memory_human:1.78Gused_memory_lua:37888used_memory_lua_human:37.00Kmaxmemory:1000000000maxmemory_human:953.67Mmaxmemory_policy:noevictionmem_fragmentation_ratio:2.59mem_allocator:jemalloc-4.0.3 # Persistenceloading:0rdb_changes_since_last_save:0rdb_bgsave_in_progress:0rdb_last_save_time:1533870359rdb_last_bgsave_status:okrdb_last_bgsave_time_sec:1rdb_current_bgsave_time_sec:-1aof_enabled:0aof_rewrite_in_progress:0aof_rewrite_scheduled:0aof_last_rewrite_time_sec:-1aof_current_rewrite_time_sec:-1aof_last_bgrewrite_status:okaof_last_write_status:ok # Statstotal_connections_received:150total_commands_processed:7126instantaneous_ops_per_sec:22total_net_input_bytes:153606total_net_output_bytes:2783917instantaneous_input_kbps:0.36instantaneous_output_kbps:8.56rejected_connections:0sync_full:1sync_partial_ok:0sync_partial_err:0expired_keys:0evicted_keys:0keyspace_hits:0keyspace_misses:0pubsub_channels:0pubsub_patterns:0latest_fork_usec:18123migrate_cached_sockets:0 # Replicationrole:masterconnected_slaves:1slave0:ip=192.168.28.71,port=6380,state=online,offset=1373,lag=1master_repl_offset:1373repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:1372 # CPUused_cpu_sys:1.65used_cpu_user:0.72used_cpu_sys_children:0.31used_cpu_user_children:0.00 # Clustercluster_enabled:0 

# Keyspace

读写数据验证

192.168.28.71:19000> SET name heheOK192.168.28.71:19000> GET name"hehe"web界面验证key已经正常写入

压测

[root@c7-node1 codis]# ./bin/redis-benchmark -h 192.168.28.71 -p 19000 -c 100 -d 100 -t set -n 10000 -r 10000

上述命令的意思是,使用redis-benchmark压力测试命令连接codis集群,同时并发10000个(-c),测试set操作(-t),每个测试数据集是100字节(-d),请求数是100000(-n),使用使用随机数插入数值(-r)。

测试结果为1秒内完成1万个set操作

====== SET ======  10000 requests completed in 0.96 seconds  100 parallel clients  100 bytes payload  keep alive: 1压测后可以看到分到后端group的数据还是比较均衡的

基于redis-sentinel实现主备切换

修改sentinel配置文件

[root@c7-node1 codis]# cat /data/redis/sentinel.conf port 26379bind 0.0.0.0 pidfile "/data/redis/logs/sentinel.pid"logfile "/data/redis/logs/sentinel.log"dir "/data/redis/db" sentinel monitor codis-server-01 192.168.28.71 6379 2sentinel down-after-milliseconds codis-server-01 5000sentinel failover-timeout codis-server-01 60000sentinel parallel-syncs codis-server-01 2 sentinel monitor codis-server-02 192.168.28.72 6380 2sentinel down-after-milliseconds codis-server-02 5000sentinel failover-timeout codis-server-02 60000sentinel parallel-syncs codis-server-02 2 sentinel monitor codis-server-03 192.168.28.73 6381 2sentinel down-after-milliseconds codis-server-03 5000sentinel failover-timeout codis-server-03 60000sentinel parallel-syncs codis-server-03 2

复制sentinel配置到其他节点

scp /data/redis/sentinel.conf 192.168.28.72:/data/redis/sentinel.confscp /data/redis/sentinel.conf 192.168.28.73:/data/redis/sentinel.conf

创建相关目录

mkdir /data/redis/logs/mkdir /data/redis/db/

启动sentinel

[root@c7-node1 codis]# pwd/data/go/src/github.com/CodisLabs/codis[root@c7-node1 codis]# nohup ./bin/redis-sentinel /data/redis/sentinel.conf &codis web页面添加sentinels

配置完成后可以在group中看到明显的HA标志

手动kill 掉一个主节点测试可用性

kill掉192.168.28.72机器上的6380主节点,验证从节点可以正常转移

验证死一台机器(手动关闭192.168.28.73节点),codis集群能否正常提供服务

数据平滑迁移

redis 数据 平滑迁移到codis 使用codis官方提供的redis-port工具。

原理:redis-port本质是以slave的形式挂载到现有redis服务上去的

1、redis会生成RDB dump文件给做为slave的redis-port

2、redis-port分析RDB文件,并拆分成key-value对,通过slotsrester指令发给codis

3、迁移过程中发生的修改,redis会将这些指令在RDB DUMP发送完成后,再发给redis-port,而redis-port收到这些指令后不做处理,而直接转发给codis

redis-port github地址: https://github.com/CodisLabs/redis-port

(1)安装redis-port

cd /data/go/src/github.com/CodisLabsgo get -u github.com/CodisLabs/redis-portgo get github.com/cupcake/rdbcd redis-port/make

数据同步命令

./bin/redis-sync -m 192.168.201.3:6381 -t 192.168.28.71:19000

参数说明:

-m 源集群地址和端口

-t 目标集群地址和端口

redis 数据扩容

说明:本次扩容添加3组codis-server,数据扩容测试由于不涉及高可用相关内容,所以扩容的codis server均为单点

(1)按照之前的部署方式,分别在三个节点各自启动了一个codis server,端口分别为6382,6383,6384,并在web管理界面添加到了集群中

(2)通过rebalance all slots来实现集群的slots自动均衡

(3)确定每个新加入的group分配的slots。

(4)分配完成slot显示如下所示

从group看,每组分片的memory空间占用情况也是均衡的

dashboard 故障异机启动

codis 官方仅允许运行一个dashboard节点,dashboard节点启动会在zk上注册自己的节点,同时在程序正常退出的时候删掉对应的节点,但如果异常退出就会导致zk的节点无法删除,在下一次启动的时候会报“zk: node already exists”的错误。

如果dashboard节点出现故障,短时间无法恢复,我们需要在另外一台节点启动dashboard的话,需要在zookeeper中删除节点的注册信息,方法如下:

# ./zkCli.shdelete /codis3/xuele-codis/topom

storage 主机集群共享卷数据不同步_codis 高可用集群跳过nginx 代理相关推荐

  1. linux集群管理平台,基于Linux平台的高可用集群管理系统的研究与实现

    摘要: 集群管理系统的高可用性是指其能够连续地对外提供服务,本文针对集群系统的高可用性,以开源的集群搭建和管理软件KUSU为基础,以集群管理节点的双机热备份技术理论为支撑,以实现集群系统的帮障检测与业 ...

  2. k8s集群部署 | 三节点(复用)高可用集群过程参考

    文章目录 1. kubeadm 部署三节点(复用)高可用 k8s 集群 1.1 环境规划阶段 1.1.1 实验架构图 1.1.2 系统版本说明 1.1.3 环境基本信息 1.1.4 k8s 网段划分 ...

  3. k8s 手动恢复redis 集群_二进制手动部署k8s-1.14高可用集群(二、集群部署)

    1. CA证书(任意节点) 1.1 安装cfssl cfssl是非常好用的CA工具,我们用它来生成证书和秘钥文件 安装过程比较简单,如下: # 下载 $ mkdir -p ~/bin $ wget h ...

  4. MHA-结合MySQL半同步复制高可用集群(Centos7)

    目录 一.理论概述 本案例部署思路 二.环境 三.部署 部署MHA 部署二进制包MySQL及部署主从复制 部署半同步复制 配置MHA MHA测试 部署lvs+keepalived(lvs1,lvs2) ...

  5. redis的主从同步及高可用集群

    redis 是一个高性能的 key-value 数据库. redis 的出现,很大程度补偿了 memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很 好的补充作用.它 ...

  6. linux高可用集群(HA)原理详解

    高可用集群 一.什么是高可用集群 高可用集群就是当某一个节点或服务器发生故障时,另一个节点能够自动且立即向外提供服务,即将有故障节点上的资源转移到另一个节点上去,这样另一个节点有了资源既可以向外提供服 ...

  7. 高可用集群原理概念详述

    一.高可用集群的定义 高可用集群,英文原文为High Availability Cluster,简称HACluster,简单的说,集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网 ...

  8. 简单的高可用集群实验

    前言: 上文介绍了高可用集群的基本概念,下面让我们来试试用两台提供web服务的虚拟机来实现一个小小的高可用集群吧- 首先,配置一个高可用集群的前提有: 1.至少两个节点: 2.共享存储(为了提供的页面 ...

  9. 生产环境kubeadm部署k8s(1.23)高可用集群

    kubeadm部署k8s高可用集群 1.设备清单 2.各节点下载docker源 3.各节点安装docker服务并加入开机启动 4.各节点配置docker加速器并修改成k8s驱动 5.各节点重启dock ...

  10. HAProxy实现负载均衡及高可用集群(corosync+pacemaker)

    一.haproxy haproxy 是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy特别适用 ...

最新文章

  1. 用百度地图API分析打交通大数据
  2. 虚拟机克隆_了解Java中的可克隆接口
  3. AI:2020年6月21日北京智源大会演讲分享之14:50-15:15穗志方教授《从语言到知识——构建语言智能的基石》
  4. python声明_【瞎折腾-03】在Python里面写类型“声明”
  5. .gitignore总结
  6. VTK:Utilities之DataAnimationSubclass
  7. (王道408考研数据结构)第二章线性表-第二节1:顺序表的定义
  8. 遇上浏览器跨域问题怎么办?
  9. C和C++ const的声明差异
  10. Leetcode18.四数之和
  11. 中控考勤机数据通过java程序读取方法
  12. CoreOS发起的友好兼容Kubernetes的存储系统:Torus
  13. 啊哈算法 --对冒泡排序python写法
  14. 技能梳理7@stm32+OLED+flash掉电保存+按键
  15. 海康威视SDK登录失败,错误码为8
  16. SQL必知必会挑战题答案
  17. AUTOCAD——对齐标注命令
  18. Dynamics 365Online 使用adal.js注册和配置SimpleSPA应用程序
  19. SQLserver 修复数据库
  20. 电流互感器输出波形测试

热门文章

  1. 信息发展树标杆 智慧城市筑屏障
  2. 行为类模式(九):策略(Strategy)
  3. OpenCV学习笔记——图像平滑处理
  4. PACKAGE-INFO.JAVA 作用及用法详解
  5. 使用uddi sdk发布服务到UDDI时的安全配置
  6. ARM开发6.3.2 基础实训( 2 ) 单个数码 LED 的显示输出系统设计( 2 )--LPC21XX
  7. hive使用适用场景_ 如何将Hive与HBase整合联用
  8. 利用iis服务器创建站点,如何使用iis建立一个网站
  9. C# 在服务器生成文件/文件夹并压缩下载到本地
  10. oracle 11g给表建触发器错误“索引中丢失 IN 或 OUT 参数:: 1