Redis
文章平均质量分 83
Redis
AirGo.
[WHY]每一个你不满意的当下,都有一个你不曾努力的过去。
展开
-
高并发下的缓存问题,这篇就够了
缓存 缓存大家都不陌生,目的是为了优化磁盘数据读取的性能问题,缓存 + DB 的架构往往如下如图所示: 但是,缓存也是一把双刃剑,用好了可以让服务性能大幅度提升,用不好,就可能为系统埋下隐患。本文就从缓存最常见的几个问题出发,讨论一下每种问题的解决方案。目前最常用的分布式缓存数据库就是 Redis 了,所以本文代码实例均以 Redis 为准。缓存雪崩 缓存目的是为了解决热点数据的访问,所以当某些数据一段时间没有被访问时,缓存会过期自动失效,假想一下...原创 2021-08-15 21:42:52 · 1169 阅读 · 0 评论 -
Redis源码之——键过期策略源码解析(惰性删除+定期取样删除)
前言从概念上讲,我只知道redis采用惰性删除加定期随机删除的策略去释放过期键的内存,但是并没有研究过其中的原理实现,今天以get命令为例,追了一下源码,剖析下惰性删除的实现过程。源码追踪命令入口在server.c文件中查找对应的命令函数,对应的方法是getCommandstruct redisCommand redisCommandTable[] = { {"module",moduleCommand,-2, "admin no-script", 0,NU原创 2020-06-25 17:04:15 · 2610 阅读 · 0 评论 -
Redis源码之——跳表skiplist原理和源码调试
码字不易,转载请附原链,搬砖繁忙回复不及时见谅,技术交流请加QQ群:909211071原理Redis的zset是一个复合结构,有以下几个特性:hash存储value-score的对应关系 按照score排序 指定score范围获取value列表 获得某个元素的排名当zset的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认为64字节)使,redis会用ziplist存储zse.原创 2020-11-26 22:12:43 · 487 阅读 · 0 评论 -
高并发场景利器之限流
WHY,为什么需要限流? 举一个常见场景,鄙人居住在北京,大天朝的地铁早高峰远近闻名,地铁人满为患,此时我们的安检员大大们会拉起长长的隔离线,乘客们有序排队进站。为什么要这样做呢,让大家自己随意进入会有什么问题呢?因为通过工作人员慢慢引流,会有效减少站台的压力,不会使大量无秩序乘客蜂拥而至堵在站台,导致想上的人上不去,想下的人下不来,地铁车门关不上,影响地铁正常行驶,还会引发冲突甚至安全事故。所以限流是为了保证每一位乘客最终能够顺利上车,同时保持整个过程井然有序。 回到我们...原创 2020-11-24 17:22:08 · 788 阅读 · 2 评论 -
Redis调试关键断点和多路复用流程
server.c ->void initServer ae.c ->int aeCreateFileEvent networking.c ->void acceptTcpHandler networking.c ->static void acceptCommonHandler networking.c ->client *createClient ae.c ->int aeCreateFileEvent networking.c -> vo...原创 2020-11-25 17:13:46 · 350 阅读 · 0 评论 -
一篇文章玩转GDB/LLDB调试Redis源码
一、安装调试版redis参考博客:https://success.blog.csdn.net/article/details/83659776注意需要在makefile的开头定义CFLAGS 变量:CFLAGS = -g ,否则调试过程中无法跟踪代码二、使用gdb启动redis-serversudo gdb /usr/local/bin/redis-server会遇到如下问题:(gdb) r Starting program: /usr/local/bin/redis-ser原创 2020-08-09 21:39:48 · 757 阅读 · 0 评论 -
Redis源码之——redisObject
定义在server.h文件中redisObject结构体#define LRU_BITS 24#define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) /* Max value of obj->lru */#define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */ #define OBJ_SHARED_REFCOUNT INT_MAXtypedef struct redisO原创 2020-06-21 19:17:25 · 528 阅读 · 0 评论 -
Redis源码之——SDS
SDS的定义/* Note: sdshdr5 is never used, we just access the flags byte directly. * However is here to document the layout of type 5 SDS strings. */struct __attribute__ ((__packed__)) sdshdr5 { unsigned char flags; /* 3 lsb of type, and 5 msb of strin原创 2020-06-20 15:20:46 · 411 阅读 · 0 评论 -
redis-cluster-proxy代理集群并支持mget命令
参考文档搭建集群:http://www.redis.cn/topics/cluster-tutorial.htmlredis-cluster-proxy:https://github.com/RedisLabs/redis-cluster-proxy搭建集群集群最少为3个节点,所以需要复制3份redis配置文件,每个文件更改下面几个地方:port:端口号 pidfile:/var/run/redis-6379.pid logfile:"/usr/local/var/log/re.原创 2020-05-09 21:17:05 · 1962 阅读 · 0 评论 -
Redis两种持久化方式原理和单机多实例持久化脚本
注意:Linux系统使用redis需要更改系统的内存分配策略,执行sysctl vm.overcommit_memory=1命令,0-2分别代表不加载、加载、允许超额加载一、RDBRDB持久化是把当前数据生成二进制快照保存到硬盘的过程。配置项:dir:保存路径 dbfilename:保存文件名 rdbcompression:是否开启压缩,默认开启,可以方便保存到硬盘和发送给从节...原创 2020-05-04 17:21:42 · 1140 阅读 · 4 评论 -
通过原理理解为什么Redis的pipeline可以有效提升性能
Redis命令执行的过程关于Redis服务如何处理每条指令已经有相关文章了,可以移步去看,这里只讨论命令发送之后的流程:客户端进程调用write操作将数据写到本地操作系统内核的发送缓冲中 客户端操作系统内核异步将数据发送到服务端机器 Redis服务端将数据从本地操作系统内核的接收缓冲中取出 执行Redis命令 服务端进程调用write操作将数据写到本地操作系统内核的发送缓冲中 服...原创 2020-05-04 14:49:23 · 1035 阅读 · 0 评论 -
Redis客户端通信协议
请求命令格式每行用\r\n分割 第一行是参数数量 第二行开始,每行以此是每个参数的字节数和参数字符串,各占一行比如:set hello redis*3$3SET$5hello$5redis上面为了方便看清,我们用换行展示,实际上发送的数据是一行:*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5redis\r\n返回格式 成功...原创 2020-04-25 14:43:12 · 551 阅读 · 0 评论 -
Redis命令时间复杂度查询表
String类型命令 时间复杂度 set 0(1) get 0(1) del 0(k),k是键的个数 mset 0(k),k是键的个数 mget 0(k),k是键的个数 incr 0(1) decr 0(1) incryby 0(1) decryby 0(1) incrybyfloat 0...原创 2020-04-19 18:40:12 · 2872 阅读 · 2 评论 -
Redis使用Lua脚本自定义原子操作
使用Lua的好处命令原子执行,执行过程中不会插入其他命令 定制命令,并存在redis中复用 一次网络IO发送多个命令,减少网络开销执行Lua的两个方法1、eval:eval 脚本内容 key个数 key列表 参数列表127.0.0.1:6379> eval 'return "hello " .. KEYS[1] .. " " .. ARGV[1]' 1 redis w...原创 2020-04-19 17:59:48 · 581 阅读 · 0 评论 -
Redis慢查询和slowlog
Redis命令执行步骤发送命令 命令排队 命令执行 返回结果慢查询只统计步骤3命令执行的时间,所以没有慢查询并不代表客户端没有超时问题。配置项slowlog-log-slower-than代表一条命令执行超过多少微秒就会记录为慢查询,默认为10000 slowlog-max-len代表慢查询日志最多存储多少条,默认为128,超出后,先记录的会被顶掉相关命令slowlog...原创 2020-04-19 17:50:02 · 495 阅读 · 0 评论 -
Redis开发和运维相关shell命令总结
redis-cli1、-r(repeat)选项代表将命令执行多次$redis-cli -r 3 pingPONGPONGPONG2、-i(interval)选项代表每隔几秒执行一次命令,必须和-r选项同时使用redis-cli -r 3 -i 1 info | grep used_memory_humanused_memory_human:1.00Mused_memo...原创 2020-04-19 17:14:12 · 294 阅读 · 0 评论 -
Redis如何处理每条指令的
响应队列redis为每个客户端socket关联了一个响应队列,redis服务通过响应队列来将指令的返回结果回复给客户端。如果队列为空,那么意味着连接暂时处于空闲状态,不需要去获取写事件,也就是可以将当前的客户端描述符从write_fds里移出来。等到队列有数据了,再将描述符放进去,避免select系统调用立即返回写事件,结果发现没有数据,这样会白白耗费CPU。定时任务redis服务器除...原创 2020-03-20 20:33:38 · 230 阅读 · 0 评论 -
php-redis源码之长连接、短连接、命令自动检活
源码函数所在文件为了避免代码影响阅读,以及代码顺序不符合个人的读码习惯,就不贴代码了,都可以通过函数名在下面几个c文件中找到redis.c library.c common.h几个核心函数 redis_connect:用于创建sock连接,第一个参数INTERNAL_FUNCTION_PARAM_PASSTHRU是宏定义,用来获取函数传入的参数,第二个参数persistent用...原创 2020-03-13 00:12:08 · 1164 阅读 · 0 评论 -
关于php-redis的pconnect长链接的思考
抛出问题前段时间有个大佬说,php-redis的pconnect并不能实现长链接,在请求结束后连接就被释放掉了,我心中存疑,如果是这样的话,那php-reds为什么还要有connect和pconnect?查找文档php-redis官方文档中有这样一句话:The connection will not be closed on end of request until the php p...原创 2020-03-12 15:45:53 · 1376 阅读 · 4 评论 -
封装php-redis服务,读写分离,失败重连,单例模式,限制客户端指令集
安装和配置安装redis服务和php-redis扩展:https://blog.csdn.net/why444216978/article/details/83659776主从复制:https://blog.csdn.net/why444216978/article/details/100170179封装服务类RedisService.php<?phpclass Red...原创 2019-12-26 21:59:13 · 612 阅读 · 0 评论 -
PHP+redis+SIGALRM信号实现队列可靠消费和消费超时控制
<?phpnamespace App\Console\Commands;use App\Services\Topics;use Illuminate\Console\Command;use PhpSpec\Exception\Exception;use Symfony\Component\Console\Input\InputOption;/** * @brief ...原创 2019-10-17 20:22:40 · 505 阅读 · 0 评论 -
Redis实现消息中心
技师端消息中心:业务场景:用户和技师一对一聊天咨询,实现技师端的消息中心。实现方法:1、用zset实现按照用户最后追问时间排序,按照时间戳排序,time:技师uid 作为zset的的key,问题id作为集合中元素的key,每次有新追问时用当前时间戳更新对应集合中对应用户的score2、用zset实现某一问题按照消息数量排序,count:技师uid作为zset的key,问题...原创 2019-08-02 17:33:32 · 1426 阅读 · 0 评论 -
GoLang封装redigo
安装redigo扩展go get -v github.com/gomodule/redigo/redispackage redisimport ( "context" "fmt" "github.com/opentracing/opentracing-go" "strconv" "strings" "time" "why/config" "why/log" "...原创 2019-10-07 12:24:13 · 759 阅读 · 0 评论 -
redis主从复制原理、搭建、以及如何规避复制风暴和全量复制
配置:1、更改IP地址2、更改port3、设置从服务器replicaof4、设置masterauth如图所示:replica为主从追踪bgsave异步全量复制saveing started by pid子进程执行success、succeeded 同步完成全量复制和部分复制:是否同步完成:通过offset对比是否一致来判断全量复制:r...原创 2019-08-31 10:47:31 · 629 阅读 · 0 评论 -
PHP和Redis中的写时复制
PHP:复制变量时,通过引用计数+1,实际内存中变量仅有一份,只有在改变某一变量的值时,才复制一份新的Redis:Redis中的RDB快照备份时,会fork出子进程来处理,此时快照的数据不再改变,为了节省内存,主进程和子进程共用内存存储数据。在数据被更新时,主进程将修改的页面(每个页面4KB)复制一份出来,对这个复制出来的页面进行修改。...原创 2019-08-26 00:47:26 · 684 阅读 · 0 评论 -
使用redis避免相同请求反复提交,实现幂等操作
方法:通过redis分布式锁场景举例:同一用户连续提交评论内容function isIdempotent( $uid, $content){ $redis = RedisService::getInstance(); $key = 'lock:' . md5($uid . $target_id . $comment); if(!empty($...原创 2019-08-02 17:45:10 · 1486 阅读 · 0 评论 -
Redis内存管理、键过期策略、内存淘汰策略
两种持久化方式参考:http://oldblog.antirez.com/post/redis-persistence-demystified.html1、RDB+AOF是最优解,AOF日志是从RDB开始到结束这段时间发生的增量AOF2、主进程fork子进程异步进行持久化写入,主进程继续服务于client,新写入数据时采用写时复制一份4KB大小的内存页3、即使AOF同步频率设置为n...原创 2019-07-16 19:51:52 · 251 阅读 · 0 评论 -
linux下安装redis服务和php扩展
一:安装redis服务1、wget http://download.redis.io/releases/redis-5.0.0.tar.gz2、tar xzf redis-5.0.0.tar.gz3、cd redis-5.0.04、yum -y install gcc5、make6、make test 如果报错类似You need tcl 8.5 or newer in ...原创 2018-11-02 18:41:03 · 1325 阅读 · 0 评论 -
redis哨兵sentinel部署和客户端实现
配置文件:port 26379 //哨兵端口号daemonize yes //守护进程pidfile "/usr/local/redis-sentinel/redis_sentinel_26379.pid" //pid目录logfile "/usr/local/redis-sentinel/redis_sentinel_26379.log" //log目录dir /usr/loca...原创 2019-09-02 01:23:36 · 632 阅读 · 0 评论 -
Redis各项运维指标监控维护字段
概括server:服务器运行的环境参数127.0.0.1:6379> info server# Serverredis_version:5.0.0 //版本redis_git_sha1:00000000 redis_git_dirty:0redis_build_id:d7f585d46da7df6aredis_mode:standalone //单机或集群os:D...原创 2019-09-04 17:42:33 · 3934 阅读 · 0 评论 -
封装Redis缓存操作类,避免缓存雪崩、缓存击穿、缓存穿透
<?php namespace App\Master\Services;use App\User;use Validator;use Illuminate\Contracts\Auth\Registrar as RegistrarContract;class CacheRedisService { private static $prefix = 'master:';...原创 2019-09-27 11:55:21 · 313 阅读 · 0 评论 -
使用Twemproxy实现Redis连接池
原理:php和twemproxy代理在同一服务器下,通过unix socket通信,proxy保持对远端redis的长连接,这样可以减少php直连redis的网络开销安装需要的工具yum install autoconfyum install automakeyum install libtool下载安装Twemproxywget https://codeload...原创 2019-09-26 20:57:20 · 637 阅读 · 0 评论 -
Redis实现分布式锁的最优方案
redis实现分布式锁有很多种方案,redis2.6以上可以用lua脚本实现加锁和设置有效期的原子性操作,但是redis2.6以下不支持lua脚本,只能采取get+setex或setnx+expire两种方案,前者忽略掉了get和setex之间的并发,而后者是忽视了ex失败的问题。最好的办法就是升级到新版本,支持set同时设置nx和ex参数,实现如下(加锁失败的循环等待没有实现,可根据业务自行实现...原创 2019-09-24 22:34:47 · 806 阅读 · 1 评论 -
Redis常用小知识点集锦
unlink删除操作懒处理,丢给后台线程异步回收内存(整个redis为一棵大树,砍掉一个树枝,丢到旁边的异步线程池焚烧)blpop/brpoplist阻塞读brpoplpush处理list消息丢失setex分布式锁,幂等,重复提交等延时队列消息内容为zset的value,处理时间为socre,轮询获取到期任务进行处理bitmapbitcount统计指定范...原创 2019-09-14 17:04:30 · 478 阅读 · 0 评论 -
Redis数据结构之——快速列表quicklist
struct ziplist<T>{ int32 zlbytes; int32 zltail_offset; int16 zllength; T[] entries; int8 zlend;}struct ziplist_compressed{ int32 size; byte[] compressed_data;}...原创 2019-09-14 14:41:33 · 216 阅读 · 0 评论 -
Redis数据结构之——intset
当set集合容纳的元素都是整数,并且元素个数较少时,redis会使用intset来存储几何元素。inset是紧凑的数组解耦股,同时支持16位、32位和64位整数。struct intset<T>{ int32 encoding; //决定整数位宽是16位、32位还是64位 int32 length; //元素个数 in...原创 2019-09-14 13:38:04 · 267 阅读 · 0 评论 -
Redis数据结构之——压缩列表ziplist
概述 为了节约内存空间使用,zset和hash容器对象在元素个数较少时采用压缩列表进行存储,压缩列表使用的是一块连续的内存空间(数组列表),元素之间紧挨存储,没有任何冗余空隙。数据结构struct ziplist<T>{ int32 zlbytes; //整个业所列表占用的字节数 int32 zltail_offset; //...原创 2019-09-14 13:32:57 · 258 阅读 · 0 评论 -
Redis源码之——hashtable和rehash
概述: 在Redis中,整个数据库所有的key-value、hash的key-value、zset中的value-score、set的key-NULL都是通过字典结构实现的。字典内部结构: hashtable结构为一维数组分桶,二维链地址链表解决hash冲突。一维数组中存储的是二维链表的第一个元素指针。//二维链表struct dictEntry...原创 2019-09-14 13:12:02 · 541 阅读 · 0 评论 -
利用PHP访问带有密码的Redis
一、首先设置Redis密码,以提供远程登陆打开redis.conf配置文件,找到requirepass,然后修改如下:? 1 requirepass yourpassword yourpassword就是redis验证密码,设置密码以后发现可以登陆,但是无法执行命令了。命令如下:? 1 redis-cli ...原创 2018-11-02 16:56:50 · 2236 阅读 · 0 评论