1.redis是码文如何加载配置文件的!!码文源码阅读,码文详细介绍
2.Redis 码文源码剖析 3 -- redisCommand
3.Redis源码阅读(1)——zmalloc
4.[redis 源码走读] maxmemory 数据淘汰策略
5.redis7.0源码阅读:Redis中的IO多线程(线程池)
6.linux怎么安装redis
redis是如何加载配置文件的!!码文源码阅读,码文源码可以详细介绍
Redis的码文启动流程中,配置文件起着关键作用。码文通过命令行中的码文redis-server,我们可以配置服务器的码文监听地址、端口、码文访问密码等。码文配置文件是码文一个文本文件,包含选项和参数,码文如bind(服务器IP)、码文prot(端口号)和requirepass(密码)等。
启动redis-server前,需要确保安装并配置好配置文件。配置文件的加载由loadServerConfig()函数负责,这个函数位于src/config.c,主要任务是读取配置文件内容,检查语法,将选项和参数解析并保存在内存中。启动时,通过读取命令行参数指定配置文件路径,如通过-p设置端口,-a设置密码。
在配置文件中,包括指令用于引用其他配置文件,如`include`。如果遇到include,dg电玩城源码Redis会调用glob()函数扩展匹配规则,将相关配置文件合并到主配置中。`loadServerConfig`函数会处理各种选项,如从标准输入读取配置(config_from_stdin)和直接从命令行参数传递的选项(options)。
解析配置文件时,loadServerConfigFromString函数将字符串形式的配置逐行处理,如跳过注释行,分割参数,然后根据配置项类型和数量执行相应的设置操作。如果遇到如`rename-command`、`user`声明或`loadmodule`等特殊指令,会有对应的处理逻辑。
总的来说,Redis的配置文件加载过程严谨且灵活,它确保了服务器能在接收到正确配置后启动,提供了丰富的配置选项来满足不同场景的需求。若想深入了解,后续会有更多关于配置文件细节的探讨。
Redis 源码剖析 3 -- redisCommand
Redis 使用 redisCommand 结构体处理命令请求,其内包含一个指向对应处理函数的 proc 指针。redisCommandTable 是一个存储所有 Redis 命令的数组,位于 server.c 文件中。此数组通过 populateCommandTable() 函数填充,该函数将 redisCommandTable 的内容添加到 server.commands 字典,将 Redis 支持的所有命令及其实现整合。
populateCommandTable() 函数中包含 populateCommandTableParseFlags() 子函数,用于将 sflags 字符串转换为对应的 flags 值。lookupCommand*() 函数族负责从 server.commands 中查找相应的命令。
Redis源码阅读(1)——zmalloc
zmalloc是一个简化内存分配的库,包含以下API函数:zmalloc
zcalloc
zrealloc
zfree
zstrdup
zmalloc_used_memory
zmalloc_set_oom_handler
zmalloc_get_rss
zmalloc_get_allocator_info
zmalloc_get_private_dirty
zmalloc_get_smap_bytes_by_field
zmalloc_get_memory_size
zlibc_free
其中,易语言源码cfzmalloc用于分配内存,zcalloc在分配内存的同时初始化为0,zrealloc用于重新分配内存,zfree用于释放内存,zstrdup用于复制字符串并分配内存,zmalloc_used_memory用于获取已分配内存的大小,zmalloc_set_oom_handler用于设置内存溢出处理器,zmalloc_get_rss用于获取当前进程的内存使用量,zmalloc_get_allocator_info用于获取分配器信息,zmalloc_get_private_dirty用于获取私有脏数据,zmalloc_get_smap_bytes_by_field用于获取指定字段的内存使用量,zmalloc_get_memory_size用于获取内存大小,zlibc_free用于释放内存。 在zmalloc中,宏函数update_zmalloc_stat_alloc用于更新used_memory的值。这个宏函数中的if语句用于补齐分配的内存字节数到sizeof(long),但是我不太理解5.0源码中为什么atomicIncr使用的是__n而不是直接对_n进行操作。测试发现,used_memory的值并未对齐到8,那么if语句的存在意义何在呢? 同样地,update_zmalloc_stat_free宏函数用于更新已释放内存的统计信息。与update_zmalloc_stat_alloc相比,虽然malloc_usable_size已经返回精确的字节数,但update_zmalloc_stat_alloc为何不直接使用atomicIncr更新used_memory呢?在Unstable分支中,已有开发者对此进行了优化。[redis 源码走读] maxmemory 数据淘汰策略
Redis 是一个内存数据库,通过配置 `maxmemory` 来限定其内存使用量。当 Redis 主库内存超出限制时,会触发数据淘汰机制,以减少内存使用量,防止技术盗源码直至达到限制阈值。
当 `maxmemory` 配置被应用,Redis 会根据配置采用相应的数据淘汰策略。`volatile-xxx` 类型配置仅淘汰设置了过期时间的数据,而 `allkeys-xxx` 则淘汰数据库中所有数据。若 Redis 主要作为缓存使用,可选择 `allkeys-xxx`。
数据淘汰时机发生在事件循环处理命令时。有多种淘汰策略可供选择,从简单到复杂包括:不淘汰数据(`noeviction`)、随机淘汰(`volatile-random`、`allkeys-random`)、采样淘汰(`allkeys-lru`、`volatile-lru`、`volatile-ttl`、`volatile-freq`)以及近似 LRU 和 LRU 策略(`volatile-lru` 和 `allkeys-lru`)。
`noeviction` 策略允许读操作但禁止大多数写命令,返回 `oomerr` 错误,仅允许执行少量写命令,如删除命令 `del`、`hdel` 和 `unlink`。
`volatile-random` 和 `allkeys-random` 机制相对直接,随机淘汰数据,策略相对暴力。
`allkeys-lru` 策略根据最近最少使用(LRU)算法淘汰数据,优先淘汰最久未使用的数据。
`volatile-lru` 结合了过期时间与 LRU 算法,优先淘汰那些最久未访问且即将过期的数据。
`volatile-ttl` 策略淘汰即将过期的数据,而 `volatile-freq` 则根据访问频率(LFU)淘汰数据,QQ业务查询-源码考虑数据的使用热度。
`volatile-lru` 和 `allkeys-lru` 策略通过采样来近似 LRU 算法,维护一个样本池来确定淘汰顺序,以提高淘汰策略的精确性。
总结而言,Redis 的数据淘汰策略旨在平衡内存使用与数据访问需求,通过灵活的配置实现高效的数据管理。策略的选择应基于具体应用场景的需求,如数据访问模式、性能目标等。
redis7.0源码阅读:Redis中的IO多线程(线程池)
Redis服务端处理客户端请求时,采用单线程模型执行逻辑操作,然而读取和写入数据的操作则可在IO多线程模型中进行。在Redis中,命令执行发生在单线程环境中,而数据的读取与写入则通过线程池进行。一个命令从客户端接收,解码成具体命令,根据该命令生成结果后编码并回传至客户端。 Redis配置文件redis.conf中可设置开启IO多线程。通过设置`io-threads-do-reads yes`开启多线程,同时配置`io-threads 2`来创建两个线程,其中一个是主线程,另一个为IO线程。在网络处理文件networking.c中,`stopThreadedIOIfNeeded`函数会判断当前需要执行的命令数是否超过线程数,若少于线程数,则不开启多线程模式,便于调试。 要进入IO多线程模式,运行redis-server命令,然后在调试界面设置断点在networking.c的`readQueryFromClient`函数中。使用redis-cli输入命令时,可以观察到两个线程在运行,一个为主线程,另一个为IO线程。 相关视频推荐帮助理解线程池在Redis中的应用,包括手写线程池及线程池在后端开发中的实际应用。学习资源包括C/C++ Linux服务器开发、后台架构师技术等领域,需要相关资料可加入交流群获取免费分享。 在Redis中,IO线程池实现中,主要包括以下步骤:读取任务的处理通过`postponeClientRead`函数,判断是否启用IO多线程模式,将任务加入到待执行任务队列。
主线程执行`postponeClientRead`函数,将待读客户端任务加入到读取任务队列。在多线程模式下,任务被添加至队列中,由IO线程后续执行。
多线程读取IO任务`handleClientsWithPendingReadsUsingThreads`通过解析协议进行数据读取,与写入任务的多线程处理机制相似。
多线程写入IO任务`handleClientsWithPendingWritesUsingThreads`包括判断是否需要启动IO多线程、负载均衡分配任务到不同IO线程、启动IO子线程执行写入操作、等待IO线程完成写入任务等步骤。负载均衡通过将任务队列中的任务均匀分配至不同的线程消费队列中,实现无锁化操作。
线程调度部分包含开启和关闭IO线程的功能。在`startThreadedIO`中,每个IO线程持有锁,若主线程释放锁,线程开始工作,IO线程标识设置为活跃状态。而在`stopThreadedIO`中,若主线程获取锁,则IO线程等待并停止,IO线程标识设置为非活跃状态。linux怎么安装redis
Linux安装Redis的步骤: 1. 下载Redis源码 访问Redis官网,下载最新稳定版本的源码包。 2. 解压源码包并编译安装 使用tar命令解压源码包,然后进入解压后的目录,执行make命令进行编译。编译完成后,执行make install进行安装。 3. 配置Redis 安装完成后,需要进行Redis的配置。进入Redis的源码目录,复制一个redis.conf配置文件到安装目录,并修改配置文件中的相关参数。 4. 启动Redis服务 进入Redis安装目录的bin目录,执行./redis-server命令启动Redis服务。也可以使用systemd或supervisord等工具来管理Redis服务的启动和停止。 以下是 下载Redis源码: 访问Redis官方网站,在“Download”页面找到适合Linux系统的源码包进行下载。通常源码包为tar.gz格式。 解压源码包并编译安装: 使用Linux系统的文件解压工具tar,将下载的源码包解压到指定目录。然后进入解压后的源码目录,执行make命令进行编译。这个过程可能需要一些依赖库的支持,如gcc等,确保系统已安装这些依赖。编译完成后,在源码目录下执行make install进行安装。 配置Redis: 安装完成后,需要配置Redis服务。进入Redis的源码目录,找到redis.conf这个配置文件,复制一份到安装目录,并根据实际需求修改配置文件中的参数,如设置端口号、绑定IP地址等。这些配置决定了Redis服务的基本运行方式。 启动Redis服务: 完成配置后,就可以启动Redis服务了。进入Redis安装目录的bin目录,执行./redis-server命令启动服务。如果需要后台运行或者希望使用systemd等工具管理Redis服务,可以在启动命令中加入相应的参数或配置。 完成以上步骤后,Linux上的Redis就已经安装并可以运行了。分析SpringBoot 的Redis源码
在Spring Boot 2.X版本中,官方简化了项目配置,如无需编写繁琐的web.xml和相关XML文件,只需在pom.xml中引入如spring-boot-starter-data-redis的starter包即可完成大部分工作,这极大地提高了开发效率。
深入理解其原理,我们研究了spring-boot-autoconfigure和spring-boot-starter-data-redis的源码。首先,配置项在application.properties中的设置会被自动映射到名为RedisProperties的类中,此类由RedisAutoConfiguration类负责扫描和配置。该类会检测是否存在RedisOperations接口的实现,例如官方支持的Jedis或Lettuce,以此来决定使用哪个客户端。
在RedisAutoConfiguration中,通过@Bean注解,它引入了LettuceConnectionConfiguration和JedisConnectionConfiguration,这两个配置类会创建RedisConnectionFactory实例。在注入RedisTemplate时,实际使用的会是第一个被扫描到的RedisConnectionFactory,这里通常是LettuceConnectionFactory,因为它们在@Import注解的导入顺序中位于前面。
自定义starter时,可以模仿官方starter的结构,首先引入spring-boot-autoconfigure,然后创建自己的配置类(如MyRedisProperties)和操作模板类(如JedisTemplete)。在MyRedisAutoConfiguration中,你需要编写相关配置并确保在spring.factories文件中注册,以便Spring Boot在启动时扫描到你的自定义配置。
以自定义my-redis-starter为例,项目结构包括引入的依赖,配置类的属性绑定,以及创建连接池和操作方法的实现。测试时,只需在Spring Boot项目中引入自定义starter,配置好相关参数,即可验证自定义starter的正确工作。
Redis底层数据结构解密?
一:摘要概述
很多 redis 的使用者都可以清晰明白的道出Redis中常用的对象如string、list、hash、set、zset,一些场景比较丰富的使用者可能会说布隆过滤器、geo、Hash等。但是对于这些对象底层实现的数据结构却是知之甚少,将会详细阐述redis中的底层数据结构。为了弥补大家的创伤,今天分享Redis底层数据结构内容。
二:SDS
string作为redis中常用对象之一,普遍用于用户信息缓存等场景。当string对象中encoding编码为embstr或raw时都是采用sds作为其底层实现
2.1 SDS结构
源码文件位于redis安装目录src下的sds.h,sds声明了五种头部类型,分别为sdshdr5、sdshdr8、sdshdr、sdshdr、sdshdr。根据字符串长度创建不同头部的sds实例
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len;
uint8_t alloc;
unsigned char flags;
char buf[];
};
属性名称作用含义
len字符串长度
alloc预分配空间大小
flags低三位用于表示sds类型,可以查看sds.h文件-行定义
buf[]存储字符串用数组
2.2 SDS与C字符串区别
区别描述
长度计算 c中的字符串长度计算需要数组遍历,但是redis中的sds自身维护了len属性。所以O(1)时间复杂度即可
缓冲区溢出c中字符串更改如果未提前做好内存分配则会内存溢出,但是sds则会根据alloc与len计算预留内存是否足够分配重新申请内存
动态扩展 缓冲区溢出已经阐述这个概念,sds的内存空间会在字符串内容变更时自动扩展计算。策略为当字符换小于1M时*2翻倍,大于1M时每次扩容1M
惰性释放 与空间预分配相似操作的还有内存惰性释放,即字符串删除某些内容后所占用的内存空间并不会立即释放,后续字符串变更扩展就无需再申请内存
二:ZipList
ziplist可以说把redis对于内存的极致操作体现的淋漓尽致,链表除了节点值之外还需要维护前后节点两个指针,并且还会造成内存碎片。压缩列表紧凑的内存布局,所有节点都维护在整块内存中处理
2.1 ZipList结构
属性名称作用含义
zlbytes列表健占用内存的总字节数,在对列表健内存重分配或者是计算zlend的时候使用
zltail 指向压缩列表起始地址的指针
zllen 压缩列表的节点数量
entry压缩列表保存的节点数据
zlend压缩列表的尾节点
2.2 Entry节点结构
属性名称作用含义
previous_entry_length 字节为单位记录上一个节点的长度,如果上一个字节长度小于占用1字节。大于占用5字节,第一个字节设置为OxFE(十进制),后面四个字节储存长度
encoding 记录content记录的数据类型以及长度。长度一、二、五字节,值的最高位为、、表示类型为字节数组,长度使用除去最高位的其它位记录。开头表示储存整数,除去最高位其他位置表示content数据长度
content 记录压缩列表记录的数据
2024-12-24 10:43
2024-12-24 09:57
2024-12-24 09:32
2024-12-24 09:18
2024-12-24 09:12
2024-12-24 08:55
2024-12-24 08:54
2024-12-24 08:47