桥下の民 - 缓存
type: channel
link: https://wordplay.work/index.php/category/缓存
items: Redis-Cluster 记录
items: 一致性哈希算法
items: Redis使用规范
items: Redis主从集群搭建
items: Redis配置及优化
items: Redis安装部署

Redis-Cluster 记录
type: item
date: 2024-03-18T02:24:00+00:00
description: 一、介绍 1.1、简介 什么是redis集群： 由于数据量过大，单个Master复制集难以承担，因此需要对多个复制集进行集群，形成水平扩展每个复制集只负责存储整个数据集的一部分，这就是Redis的集群，其作用是提供在多个Redis节点间共享数据的程序集。 功能： redis集群支持多个master，每个master又可以挂在多个slave。具有读写分离、数据高可用的效果。 由于集群自带了哨兵的故障转移机制，内置了高可用的支持，所以使用集群无需再去使用哨兵功能。 客户端与redis的节点连接，不再需要连接集群中所有的节点，只需要任意连接集群中的一个可用节点即可。 槽位slot负责分配到各个物理服务节点，由对应的集群来负责维护节点，插槽和数据之间的关系。 Redis 集群的数据分片： Redis 集群没有使用一致性hash，而是引入哈希槽的概念。Redis 集群有16384个哈希槽，每个key通过CRC16校验后对16384取模来决定放置哪个槽，集群的每个节点负责部分hash槽，举个例子，比如当前集群有3个节点，那么: 分片是什么： 使用Redis集群时我们会将存储的数据分散到多台redis机器上，这称为分片。简言之，集群中的每个Redis实例都被认为是整个数据的一个分片。 如何找到给定key的分片： 为了找到给定key的分片，我们对key进行CRC16(key)算法处理并通过对总分片数量取模。然后，使用确定性哈希函数，这意味着 给定的key将多次始终映射到同一个分片，我们可以推断将来读取特定key的位置。 1.2、分片与槽位slot的优势 最大优势，方便扩缩容和数据分派查找： 这种结构很容易添加或者删除节点,比如如果我想新添加个节点D，我需要从节点 A,B,C中得部分槽到D上，如果我想移除节点A，需要将A中的槽移到B和C节点上，然后将没有任何槽的A节点从集群中移除即可，由于从一个节点将哈希槽移动到另一个节点并不会停止服务，所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。 1.3、为什redis集群的最大槽数时16384个 正常的心跳数据包带有节点的完整配置，可以用幂等方式用旧的节点替换旧节点，以便更新旧的配置。 这意味着它们包含原始节点的插槽配置，该节点使用2k的空间和16k的插槽，但是会使用8k的空间（使用65k的插槽）。 同时，由于其他设计折衷，Redis集群不太可能扩展到1000个以上的主节点。 因此16k处于正确的范围内，以确保每个主机具有足够的插槽，最多可容纳1000个矩阵，但数量足够少，可以轻松地将插槽配置作为原始位图传播。请注意，在小型群集中，位图将难以压缩，因为当N较小时，位图将设置的slot / N位占设置位的很大百分比。 (1)如果槽位为65536，发送心跳信息的消息头达8k，发送的心跳包过于庞大。 在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时，这块的大小是: 65536÷8÷1024=8kb 在消息头中最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为16384时，这块的大小是: 16384÷8÷1024=2kb 因为每秒钟，redis节点需要发送一定数量的ping消息作为心跳包，如果槽位为65536，这个ping消息的消息头太大了，浪费带宽。 (2)redis的集群主节点数量基本不可能超过1000个。 集群节点越多，心跳包的消息体内携带的数据越多。如果节点过1000个，也会导致网络拥堵。因此redis作者不建议redis cluster节点数量超过1000个。 那么，对于节点数在1000以内的redis cluster集群，16384个槽位够用了。没有必要拓展到65536个。 (3)槽位越小，节点少的情况下，压缩比高，容易传输 Redis主节点的配置信息中它所负责的哈希槽是通过一张bitmap的形式来保存的，在传输过程中会对bitmap进行压缩，但是如果bitmap的填充率slots / N很高的话(N表示节点数)，bitmap的压缩率就很低。 如果节点数很少，而哈希槽数量很多的话，bitmap的压缩率就很低。 1.4、槽位映射的发展 第一阶段：哈希取余分区 2亿条记录就是2亿个Kv，我们单机不行必须要分布式多机，假设有3台机器构成一个集群，用户每次读写操作都是根据公式hash(key)% N个机器台数，计算出哈希值，用来决定数据映射到哪一个节点上。 优点: 简单粗暴，直接有效，只需要预估好数据规划好节点，例如3台、8台、10台，就能保证一段时间的数据支撑。使用Hash算法让固定的-到同一台服务器上，这样每台服务器固定处理一部分请求(并维护这些请求的信息)，起到负载均衡+分而治之的作用。 缺点: 原来规划好的…

一致性哈希算法
type: item
date: 2023-06-25T17:27:00+00:00
description: 一、安装redis集群 cluster(集群)模式-docker版，哈希槽分区进行亿级数据存储。 1.1、问题 1~2 亿条数据需要缓存，请问如何设计这个存储案例。 单机单台 100% 不可能，肯定是分布式存储，用redis如何落地？ 1.2、哈希取余分区 2亿条记录就是2亿个 k,v，我们单机不行必须要分布式多机，假设有3台机器构成一个集群，用户每次读写操作都是根据公式： hash(key) % N个机器台数，计算出哈希值，用来决定数据映射到哪一个节点上。 优点： 简单粗暴，直接有效，只需要预估好数据规划好节点，例如3台、8台、10台，就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上，这样每台服务器固定处理一部分请求（并维护这些请求的信息），起到负载均衡+分而治之的作用。 缺点： 原来规划好的节点，进行扩容或者缩容就比较麻烦了额，不管扩缩，每次数据变动导致节点有变动，映射关系需要重新进行计算，在服务器个数固定不变时没有问题，如果需要弹性扩容或故障停机的情况下，原来的取模公式就会发生变化：Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化，根据公式获取的服务器也会变得不可控。某个redis机器宕机了，由于台数数量变化，会导致hash取余全部数据重新洗牌。 二、步骤 2.1、算法构建一致性哈希环 一致性哈希环： 一致性哈希算法必然有个hash函数并按照算法产生hash值，这个算法的所有可能哈希值会构成一个全量集，这个集合可以成为一个hash空间[0,2^32-1]，这个是一个线性空间，但是在算法中，我们通过适当的逻辑控制将它首尾相连(0 = 2^32),这样让它逻辑上形成了一个环形空间。 它也是按照使用取模的方法，前面笔记介绍的节点取模法是对节点（服务器）的数量进行取模。而一致性 Hash 算法是对2^32取模，简单来说，一致性 Hash 算法将整个哈希值空间组织成一个虚拟的圆环，如假设某哈希函数H的值空间为 0-2^32-1（即哈希值是一个32位无符号整形），整个哈希环如下图：整个空间按顺时针方向组织，圆环的正上方的点代表0，0点右侧的第一个点代表1，以此类推，2、3、4、……直到 2^32-1，也就是说0点左侧的第一个点代表 2^32-1， 0 和 2^32-1 在零点中方向重合，我们把这个由2^32个点组成的圆环称为Hash环。 2.2、服务器IP节点映射 节点映射： 将集群中各个IP节点映射到环上的某一个位置。 将各个服务器使用Hash进行一个哈希，具体可以选择服务器的IP或主机名作为关键字进行哈希，这样每台机器就能确定其在哈希环上的位置。假如4个节点NodeA、B、C、D，经过IP地址的哈希函数计算(hash(ip))，使用IP地址哈希后在环空间的位置如下： 2.3、key落到服务器的落键规则 当我们需要存储一个kv键值对时，首先计算 key 的 hash 值，hash(key)，将这个 key 使用相同的函数Hash计算出哈希值并确定此数据在环上的位置，从此位置沿环顺时针“行走”，第一台遇到的服务器就是其应该定位到的服务器，并将该键值对存储在该节点上。 如我们有Object A、Object B、Object C、Object D四个数据对象，经过哈希计算后，在环空间上的位置如下：根据一致性Hash算法，数据A会被定为到Node A上，B被定为到Node B上，C被定为到Node C上，D被定为到Node D上。 四、优点 4.1、一致性哈希算法的容错性 容错性： 假设Node C宕机，可以看到此时对象A、B、D不会受到影响，只有C对象被重定位到Node D。一般的，在一致性Hash算法中，如果一台服务器不可用，则受影响的数据仅仅是此服务器到其环空间中前一台服务器（即沿着逆时针方向行走遇到的第一台服务器）之间数据，其它不会受到影响。简单说，就是C挂了，受到影响的只是B、C之间的数据，并且这些数据会转移到D进行存储。 4.2、一致性哈希算法的扩展性 扩展性： 数据量增加了，需要增加一台节点NodeX，X的位置在A和B之间，那收到影响的也就是A到X之间的数据，重新把A到X的数据录入到X上即可，不会导致hash取余全部数据重新洗牌。 五、缺点 一致性哈希算法的数据倾斜问题 Hash环的数据倾斜问题 一致性Hash算法在服务节点太少时，容易因为节点分布不均匀而造成数据倾斜（被缓存的对象大部分集中缓存在某一台服务器上）问题，例如系统中只有两台服务器： 六、总结 为了在节点数目发生改变时尽可能少的迁移数据。 将所有的存储节点排列在收尾相接的Hash环上，每个key在计算Hash后会顺时针找到临近的存储节点存放。而当有节点加入或退出时仅影响该节点在Hash…

Redis使用规范
type: item
date: 2022-06-03T08:18:00+00:00
description: 本文档制定使用Redis规范和使用要求，制定规范命名和流程化的使用规则，从而降低后期维护、扩容、管理的成本。 一、名词释义 Redis 可基于内存亦可持久化的日志型、Key-Value 数据库。 TableName 实体类名称,例如 bi_menu 表对应的实体类是 BiMenu。 PrimaryKeyValue 某个表的主键值。 Column 实体类里面的字段名称。例如 bi_menu 表对应的实体类字段名称 name。 ColumnValue 列的值。 index 字符串 index 代表此 key 是用来记录索引的。 sort 字符串 sort 代表此 key 是用来排序标记的。 二、开发规则 2.1、key 命名 1、存放表里面所有字段信息。TableName: PrimaryKeyValue: Column 2、存放表里面某一列的信息 TableName：Column：ColumnValue 3、存放表里面某一行object信息。TableName: PrimaryKeyValue 4、存放表里面的索引。TableName: index: Column 5、存放表里面的字段排序。TableName: sort: Column bi_menu (菜单按钮) CREATE TABLE bi_menu ( id VARCHAR(36) NOT NULL PRIMARY KEY COMMENT '主键', name VARCHAR(200) NULL COMMENT '名称', sequence INT(11) NULL COMMENT '序列', description VARCHAR(200) NULL COMMENT '描述', logo VARCHAR(200) NULL COMMENT '图标', url VARCHAR(200) NULL COMMENT '访问地址' ); 类型1(value就是具体的值) BiMenu:1:id 1 BiMenu:1:name 系统应用 BiMenu:1:sequence 1 BiMenu:1:description 这是系统应用的按钮 BiMenu:1:logo 图片地址 BiMenu:1:url http://localhost:8080/aa.do 类型2(value就是该行的主键值PrimaryKeyValue) BiMenu:name:系统应用 1 BiMenu:url:http://www.baidu.com 1 类型3(value是该行数据的jason格式) BiMenu:1 { "id": "1", "name": "系统应用", " sequence ": "1", " description ": "这是系统应用的按钮" } 类型4(value是该行数据的主键值PrimaryKeyValue) BiMenu:index:id BiMenu:1 BiMenu:index:id BiMenu:2 BiMenu:index:id BiMenu:3 类型5(value是该行数据的主键值PrimaryKeyValue) BiMenu:sort:sequence BiMenu:1 BiMenu:sort:sequence BiMenu:2 BiMenu:sort:sequence BiMenu:3

Redis主从集群搭建
type: item
date: 2022-06-02T09:55:00+00:00
description: 环境准备 redis-server： 192.168.25.128:6379 主 redis6379.conf 192.168.25.128:6380 从 redis6380.conf 192.168.25.128:6381 从 redis6381.conf 一、redis 一主二从 主节点 redis6379.conf 配置 port 6379 daemonize yes bind 192.168.25.128 requirepass 123456 pidfile /usr/local/redis/etc/redis_pid_6379.pid logfile /usr/local/redis/etc/redis_6379.log dbfilename dump6379.rdb 从节点 redis6380.conf redis6381.conf 配置 port 6380 #6381 daemonize yes bind 192.168.25.128 requirepass 123456 masterauth 123456 pidfile /usr/local/redis/etc/redis_pid_6380.pid logfile /usr/local/redis/etc/redis_6380.log dbfilename dump6380.rdb slaveof 192.168.25.128 6379 分别启动三个 redis 实例 /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis6379.conf /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis6380.conf /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis6381.conf 执行info replication查看当前主从配置 192.168.25.128:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=192.168.25.128,port=6380,state=online,offset=211,lag=1 slave1:ip=192.168.25.128,port=6381,state=online,offset=211,lag=1 master_repl_offset:211 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:210 192.168.25.128:6380> info replication # Replication role:slave master_host:192.168.25.128 master_port:6379 master_link_status:up master_last_io_seconds_ago:9 master_sync_in_progress:0 slave_repl_offset:29 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 192.168.25.128:6381> info replication # Replication role:slave master_host:192.168.25.128 master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:43 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 如果如上图所示没有发现从节点，很有可能是防…

Redis配置及优化
type: item
date: 2022-06-02T09:48:00+00:00
description: 一、基本配置 # 当配置中需要配置内存大小时，可以使用 1k, 5GB, 4M 等类似的格式，其转换方式如下(不区分大小写) # # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1mb => 1024*1024 bytes # 1g => 1000000000 bytes # 1gb => 1024*1024*1024 bytes # # 内存配置大小写是一样的.比如 1gb 1Gb 1GB 1gB # daemonize no 默认情况下，redis不是在后台运行的，如果需要在后台运行，把该项的值更改为yes daemonize yes # 当redis在后台运行的时候，Redis默认会把pid文件放在/var/run/redis.pid，你可以配置到其他地址。 # 当运行多个redis服务时，需要指定不同的pid文件和端口 pidfile /var/run/redis.pid # 指定redis运行的端口，默认是6379 port 6379 # 指定redis只接收来自于该IP地址的请求，如果不进行设置，那么将处理所有请求， # 在生产环境中最好设置该项 # bind 127.0.0.1 # Specify the path for the unix socket that will be used to listen for # incoming connections. There is no default, so Redis will not listen # on a unix socket when not specified. # # unixsocket /tmp/redis.sock # unixsocketperm 755 # 设置客户端连接时的超时时间，单位为秒。当客户端在这段时间内没有发出任何指令，那么关闭该连接 # 0是关闭此设置 timeout 0 # 指定日志记录级别 # Redis总共支持四个级别：debug、verbose、notice、warning，默认为verbose # debug 记录很多信息，用于开发和测试 # varbose 有用的信息，不像debug会记录那么多 # notice 普通的verbose，常用于生产环境 # warning 只有非常重要或者严重的信息会记录到日志 loglevel debug # 配置log文件地址 # 默认值为stdout，标准输出，若后台模式会输出到/dev/null #logfile stdout logfile /var/log/redis/redis.log # To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. # syslog-enabled no # Specify the syslog identity. # syslog-ident redis # Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. # syslog-facility local0 # 可用数据库数 # 默认值为16，默认数据库为0，数据库范围在0-（database-1）之间 databases 16 ################################ 快照 ################################# # # 保存数据到磁盘，格式如下: # # save <seconds> <changes> # # 指出在多长时间内，有多少次更新操作，就将数据同步到数据文件rdb。 # 相当于条件触发抓取快照，这个可以多个条件配合 # # 比如默认配置文件中的设置，就设置了三个条件 # # save 900 1 900秒内至少有1个key被改变 # save 300 10 300秒内至少有300个key被改变 # save 60 10000 60秒内至少有10000个key被改变 save 900 1 save 300 10 save 60 10000 # 存储至本地数据库时（持久化到rdb文件）是否压缩数据，默认为yes rdbcompression yes # 本地持久化数据库文件名，默认值为dump.rdb dbfilename dump.rdb # 工作目录 # # 数据库镜像备份的文件放置的路径。 # 这里的路径跟文件名要分开配…

Redis安装部署
type: item
date: 2022-06-01T12:11:00+00:00
description: 一、编译安装 下载、解压 wget http://download.redis.io/releases/redis-3.2.8.tar.gz tar -zxvf redis-3.2.8.tar.gz cd redis-3.2.8 make 编译 编译之前 00-RELEASENOTES BUGS CONTRIBUTING COPYING deps INSTALL Makefile MANIFESTO README.md redis.conf runtest 编译完成之后，可以看到解压文件redis-3.0.7 中会有对应的src、conf等文件。 二、部署文件结构 首先为了方便管理，将 Redis 文件中的 conf 配置文件和常用命令移动到统一文件中。 创建以下文件目录 mkdir -p /usr/local/redis/bin mkdir -p /usr/local/redis/etc 切换到redis-3.2.8目录，移动redis.conf配置文件： mv /home/payn/redis-3.2.8/redis.conf /usr/local/redis/etc 继续进入到src目录执行其他文件移动： mv mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server redis-trib.rb /usr/local/redis/bin 三、配置和启动 redis 服务 编辑redis.conf cd /usr/local/redis/etc vi redis.conf 需要修改的参数 --后台运行 daemonize yes --端口号 port 63700 --和哪个网卡绑定，和客户端是什么网段没有关系，这里我绑定的是内网网卡, bind 192.168.25.128 -- AES("https://github.com/Tinywan/Lua-Nginx-Redis/blob/master/Redis/redis-install.md") 加密 -- 结果：b6Pbc42gP8hXPNLzZaDnhREijtn1BSVSIYTkhTXw8SuPGpWZvN5kVpVeEVBdEQDw7M/+EZuDS6FxTOtgD2QrPe6014LPEdv2DY+YSUQZ4cE= requirepass b6Pbc42gP8hXPNLzZaDnhREijtn1BSVSIYTkhTXw8SuPGpWZvN5kVpVeEVBdEQDw7M/+EZuDS6FxTOtgD2QrPe6014LPEdv2DY+YSUQZ4cE= -- db文件名 dbfilename dump63700.rdb -- log 日志文件路径 logfile "/usr/local/redis/etc/redis_63700.log" -- 安全考虑，rename-command 配置以下命令 rename-command FLUSHALL "payngithubFLUSHALL" rename-command CONFIG "payngithubCONFIG" rename-command SHUTDOWN "payngithubSHUTDOWN" rename-command DEBUG "payngithubDEBUG" 启动 redis 服务，并指定启动服务配置文件，检测运行端口，为了安全，请不要使用 root 用户去启动。 $ sudo chown -R www:www /usr/local/redis/ //赋予指定该用户组，而非root账号 $ /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis6379.conf $ ps -aux | grep redis www 70764 0.6 0.1 38160 0:00 /usr/local/redis/bin/redis-server 127.0.0.1:63700 www 70768 0.0 0.0 15984 0:00 grep --color=auto redis redis-cli启动、检测重置命令是否生效（结果：配置文件已经OK）。 $ redis-cli -h 127.0.0.1 -p 63700 -a b6Pbc42gP8hXPNLzZaDnhREijtn1BSVSIYTkhTXw8SuPGpWZvN5kVpVeEVBdEQDw7M/+EZuDS6FxTOtgD2QrPe6014LPEdv2DY+YSUQZ4cE= 127.0.0.1:63700> set userna…