redis高性能键值数据库技术简介

embedded/2024/11/16 23:15:59/

redis_0">什么是redis

redis是远程字典服务(Remote Dictionary Server )的简写,是一个完全开源的高性能的Key-Value数据库,提供了丰富的数据结构如string、Hash、List、SetSortedset等等。数据是存在内存中的,同时Redis支持事务、持久化、LUA脚本、发布订阅、缓存淘汰、流技术等特性,提供了主从模式、Redis Sentinel和Redis cluster集群架构方案。

redis_3">安装redis

yum方式安装

sudo yum install redis
sudo systemctl enable redis
sudo systemctl start redis

yum方式版本比较落后,无法安装最新版的redis,如果需要安装最新版本的redis需要使用源码安装的方式

源码方式安装

# 检查环境依赖
yum install gcc -y
# 下载Redis源码,一般下载到/opt目录下,/opt/software
wget http://download.redis.io/releases/redis-7.0.2.tar.gz
# 解压缩到当前目录(/opt/module)  
tar zxvf /opt/software/redis-7.0.2.tar.gz  
# 编译并安装 redis  (默认安装在/usr/local/bin目录下)
make && make install 
# 启动redis	
redis-server

安装目录(/usr/local/bin)中的文件结构
安装目录
配置redis.conf文件

# 进入redis解压目录
cd redis-7.0.2
# 备份redis.conf文件
cp redis.conf redis.conf.bak
# 将redis改为后台执行,替换daemonize no为daemonize yes
sed -i 's/^daemonize no/daemonize yes/' "redis.conf"# 将redis改为可在外网访问,替换bind 127.0.0.1 -::1为bind 0.0.0.0
sed -i 's/^bind 127.0.0.1 -::1/bind 0.0.0.0/' "redis.conf"# 配置redis密码,这里使用root作为密码,替换requirepass foobared为requirepass root
sed -i 's/^# requirepass foobared/requirepass root/' "redis.conf"# 按照配置文件要求启动redis服务
redis-server redis.cnof

redis_46">redis数据类型

数据类型解释作用
String字符串类型二进制安全的数据类型,可以用来存储任何类型的数据
List列表类型Redis列表是简单的字符串列表,按照插入顺序排序
Hash哈希表存储键值对,使用存储对象
Set集合类型String类型的无序集合,集合中不能存在重复的数据。底层通过hash来实现
ZSet有序集合String类型的有序集合,集合中不能存在重复的数据。每个元素关联一个double类型的分数,底层通过hash来实现。
GEO地理空间地理位置,坐标、距离等
HyperLogLog基数统计在输入元素数量或体积非常大时,计算基数所需时间和空间总是固定的
Bitmap位图二进制的bit数组
Bitfield位域连续的比特位
Stream用于消息队列(一般不是用)

String类型底层原理
String类型是redis最基本的数据类型,
SDS 简单动态字符串,SDS有的三个属性int len、int free、char buf[]。
len保存了字符串的长度
free表示buf数组中未使用的字节数量
buf数组则是保存字符串的每一个字符元素
在这里插入图片描述

Redis与C原生字符串相比:
1、C原生字符串不会记录长度,每次获取字符串长度时间复杂度都为O(n),Redis读取len中的数值即可,时间复杂度为O(1)。
2、C原生字符串拼接,如果分配空间不够会造成缓存区溢出的情况,SDS会现根据len中的数值判断空间是否足够,如果不够会进行相应的空间扩展,所以不会出现缓存区溢出的情况。
3、SDS提供空间预分配和惰性空间释放两种策略,在给字符串分配空间时,分配的空间比字符串实际所需空间大很多,这样能减少字符串增长带来的内存重新分配次数。当字符串被缩短时,SDS不会立即收回空间,而是通过free属性将空余的空间记录下来,等后面需要使用的时候再释放这些空间。
空间分配原则:当修改字符串后的长度len小于1MB,就会预分配和len一样长度的空间,即len=free;若是len大于1MB,free分配的空间大小就为1MB。
举个例子:
如果进行修改之后, SDS 的 len 将变成 13 字节, 那么程序也会分配 13 字节的未使用空间, SDS 的 buf 数组的实际长度将变成 13 + 13 + 1 = 27 字节(额外的一字节用于保存空字符)。
如果进行修改之后, SDS 的 len 将变成 30 MB , 那么程序会分配 1 MB 的未使用空间, SDS 的 buf 数组的实际长度将为 30 MB + 1 MB + 1 byte 。

List类型底层源码分析
redis3,2版本后,List类型通过quickList作为默认底层实现,quickList本质上是一个双端链表,可以认为是linkedList和ZipList的结合体。
LinkedList
LinkedList是一个普通的链表,LinkedList每一个节点的空间都是不连续的,所以可能造成过多的空间碎片。
ziplist
ziplist是为了节省内存而开发的一种压缩列表数据结构
zipList结构

zlbytes: 4字节,记录 ziplist 整个结构体的占用空间大小。用于内存重分配或计算zlend位置。
zltail: 4字节, 记录整个 ziplist 中最后一个 entry 的偏移量。用于快速定位到尾节点。
zllen: 4字节, 记录 entry 的数量,该值被固定为 2^16 - 1。 大于这个值就必须要遍历整个结构了。
entry: 真正存数据的结构。
zlend: 1字节, 为 ziplist 的结束标识。

entry节点结构
prelen:记录了前一个节点的长度。通过这个值,可以进行指针计算,从而跳转到上一个节点。如果前一节点的长度小于254字节,则prelen属性需要用1字节长的空间来保存;如果前一节点的长度大于等于254字节,则需要用5字节长的空间来保存。
encoding:记录了节点的content属性所保存数据的类型以及长度。编码的最高位用于标识数据类型(整数或字节数组),其余位用于表示内容的长度。
entry-data:保存节点的值

quicklist
quicklist存储了一个双向列表,每个列表的节点是一个ziplist
quickList结构图
quicklist同样采用了linkedlist的双端列表特性,然后quicklist中的每个节点又是一个ziplist,所以quicklist就是综合平衡考虑了空间碎片和读写性能两个维度。使用quicklist需要注意以下2点:
1、如果ziplist中的entry个数过少,极端情况就是只有1个entry,此时就相当于退化成了一个普通的linkedlist。
2、如果ziplist中的entry过多,那么也会导致一次性需要申请的内存空间过大,而且因为ziplist本身的就是以时间换空间,所以会过多entry也会影响到列表对象的读写性能。
ziplist中的entry个数可以通过参数list-max-ziplist-size来控制

Redis持久化
redis为什么需要持久化?
Redis持久化的意义就是为了保证突然宕机,内存数据不会全部丢失。
RDB机制
RDB持久化是周期性的把redis当前内存中的全量数据写入到一个快照文件中
快照文件是一个二进制文件,包含了 Redis 在某个时间点内的所有数据。

redis6.0之前,RDB的频率为15分钟1个变化、5分钟10个变化,1分钟1万个变化,
redis6.2之后,RDB的频率为1小时1个变化,5分钟100个变化,1分钟1万个变化。

自动触发
再配置文件redis.conf中修改以下配置:
修改快照时间
save 5 2
修改文件保存路径
dir 文件路径
修改文件名称
dbfilename 文件名称.rdb

进入redis检查配置文件是否成功
config get save
config get dir
config get dbfilename

RDB会读取dump.rdb文件进行恢复,所以服务要与备份分机隔离。不可以把备份文件dump.rdb与生茶redis服务器放在同一台机器上,必须分开各自存储,以防止生产机物理损坏后备份文件也跟着挂了。

手动触发
手动执行有两个命令:save和bgsave

save:阻塞主进程,直到生成新的RDB文件;执行save命令期间,Redis不能处理其他命令。在生产中严禁使用该命令。
bgsave:异步生成RDB文件,fork子进程去生成新的RDB文件,主进程不阻塞。


http://www.ppmy.cn/embedded/138119.html

相关文章

Verilog HDL学习笔记

Verilog HDL(Hardware Description Language)是在一种硬件描述语言,类似于计算机的高级编程设计语言,它具有灵活性高,容易学习和使用等特点,同时Verilog能够通过文本的形式来描述数字系统的硬件结构和功能。…

GPT o1 模型使用及API调用

智匠MindCraft最新加入的o1-preview和o1-mini模型。本文将详细介绍这两款模型的技术参数、应用场景及价格对比。 1. o1-preview模型 最大输入:128K tokens最大输出:32K tokens输入价格:107元/百万tokens输出价格:426元/百万tokens…

第八章 利用css制作导航菜单

8.1 水平顶部导航栏 水平菜单导航栏式网站设计中应用范围最广的导航设计,一般放置在页面的顶部。水平导航实用性强,几乎所有的类型的网站都可以使用,设计难度较低 如果导航过于普通,无法容纳复杂的信息结构,就需要在…

【JavaScript】LeetCode:96-100

文章目录 96 单词拆分97 最长递增子序列98 乘积最大子数组99 分割等和子集100 最长有效括号 96 单词拆分 动态规划完全背包:背包-字符串s,物品-wordDict中的单词,可使用多次。问题转换:s能否被wordDict中的单词组成。dp[i]&#x…

沈阳乐晟睿浩科技有限公司抖音小店保障

在当今这个数字化时代,电子商务行业以其便捷性、高效性和广泛的覆盖面,成为了推动经济发展的新引擎。沈阳乐晟睿浩科技有限公司,作为这股变革洪流中的佼佼者,凭借其深厚的技术实力、敏锐的市场洞察力和前瞻性的战略布局&#xff0…

微服务架构面试内容整理-SpringCloud Netflix‌与Spring Cloud Alibaba比较

Spring Cloud Netflix 和 Spring Cloud Alibaba 都是用于构建微服务架构的解决方案,但它们在设计理念、组件和使用场景上存在一些差异。以下是它们的比较: 1. 服务注册与发现 ● Spring Cloud Netflix:使用 Eureka 作为服务注册和发现的组件。Eureka 是基于 REST 的,适合服…

php preg_match 不到内容,修改pcre.backtrack_limit解决问题

使用 preg_match 匹配不到内容,感觉是有字符串长度限制,经测试果然。 设置 pcre.backtrack_limit 大小解决问题 // php 文件中通过ini_set 修改 ini_set(pcre.backtrack_limit, 999999999); // 或 ini_set(pcre.backtrack_limit, -1);或是php.ini中修改…

机器学习—为什么我们需要激活函数

如果我们使用神经网络中每个神经元的线性激活函数,回想一下这个需求预测示例,如果对所有节点使用线性激活函数,在这个神经网络中,事实证明,这个大神经网络将变得与线性回归没有什么不同,所以这将挫败使用神…