首页 > 数据库 >redis

redis

时间:2024-07-11 11:28:05浏览次数:9  
标签:redis 元素 Redis 列表 集合 哈希 字符串

一、redis概述

(一)什么是redis?

        Redis(Remote Dictionary Server)是一个开源的、基于内存的、可选持久化的日志型Key-Value数据库编写,支持网络操作,并提供多种语言的API。Redis支持多种数据结构,包括字符串(string)、列表(list)、集合(set)、有序集合(zset)和哈希(hash),并且这些数据类型都支持丰富的操作,如push/pop、add/remove以及取交集、并集和差集等,这些操作都是原子性的。

        Redis将数据存储在内存中,以保证高速的读写操作,同时支持将数据周期性地写入磁盘或记录追加操作,以实现持久化。它还支持主从同步,允许数据从主服务器复制到多个从服务器,以确保数据的高可用性和备份。

        Redis的性能非常高,它在某些测试中实现了每秒读取110,000次和写入81,000次的速度。为了实现高并发性能,Redis使用非阻塞I/O和IO多路复用技术,如epoll(在Linux上)。 此外,Redis还提供了多种特性,如发布/订阅、Lua脚本、事务、管道、位图、键过期和哨兵监控机制等。它的一些优势包括简单稳定的源码、单线程模型、快速的单节点读写速度、丰富的数据类型、数据持久化能力、数据备份功能以及原子性操作。

        总的来说,Redis是一个高性能、多功能的Key-Value数据库,适用于多种应用场景,如数据库、缓存和消息中间件,并且在计时器、消息队列、排行榜、社交网络等领域有广泛的应用。

(二)redis为什么这么快?

1.redis单线程

主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。

2.redis采用多路复用的技术

从 redis6.x 开始采 io 多路复⽤ ,让 单个线程⾼效的处理多个连接请求 (尽量减少⽹络 IO 的时间消耗),将最耗时的 Socket 的 读取、请求解析、写⼊单独 外包 出去,剩下的 命令执⾏仍然由主线程串⾏执⾏并和内存的数据交互

(三)redis的数据结构

Redis⽀持五种主要数据结构:字符串(Strings)、列表(Lists)、哈希表(Hashes)、集合(Sets)和有序集合(Sorted Sets)。这些数据结构为开发者提供了灵活 的数据操作⽅式,满⾜了不同场景下的数据存储需求。 • 字符串(Strings):最基本的数据类型,可以包含任何数据,如数字、字符串、⼆进制数据等。在Redis中,字符串是⼆进制安全的,这意味着它们可以有任何⻓度, 并且不会因为包含空字符⽽被截断。 • 列表(Lists):简单的字符串列表,按照插⼊顺序排序。你可以添加⼀个元素到头部(左边)或者尾部(右边)。 • 哈希表(Hashes):是键值对的集合,是字符串类型的字段和值的映射表。适合存储对象。 • 集合(Sets):是字符串类型的⽆序集合。它是通过哈希表实现的,可以做到添加、删除、查找的时间复杂度都是O(1)。 • 有序集合(Sorted Sets):和Sets相似,但每个字符串元素都会关联⼀个浮点数类型的分数。元素的分数⽤来排序,如果两个成员有相同的分数,那么他们的排名按 照字典序计算。

1.简单动态字符串

优势 • 预分配:SDS会为buf分配额外的未使⽤空间(通过free字段记录),这意味着当你向⼀个SDS字符串追加内容时,如果未使⽤空间⾜够,Redis就不需要重新分配内存。这减少了内存分配次数,从⽽提⾼了性能。 • 常数时间复杂度获取字符串⻓度:由于SDS结构内部维护了⼀个len字段来记录字符串的当前⻓度,获取字符串⻓度的操作可以在常数时间复杂度O(1)内完成,⽽ 不需要像C语⾔的原⽣字符串那样遍历整个字符串。 • ⼆进制安全:SDS可以存储任意⼆进制数据,包括空字符\0。C语⾔的原⽣字符串以空字符作为结束标志,这限制了它们不能包含空字符。⽽SDS则通过len字段 来明确字符串的⻓度,因此不受此限制。 • 兼容C语⾔字符串函数:尽管SDS提供了⾃⼰的⼀套 API 来进⾏字符串操作,但它的buf字段实际上就是⼀个普通的C字符串(以\0结尾),这意味着在必要时, 可以直接使⽤标准的C语⾔字符串处理函数来操作buf字段(尽管通常不推荐这样做,因为可能会破坏SDS结构的完整性)。

2.列表的底层实现:双向链表与压列表

压缩列表:当列表的元素数量较少且元素较⼩时,Redis会使⽤压缩列表(ziplist)作为底层实现来节省内存。压缩列表是⼀个紧凑的、连续的内存块, 它按顺序存储了列表中的元素。 • ZLBYTE: 压缩列表的头部信息,包含了特殊编码和压缩列表的⻓度信息。 • LEN: 每个元素前的⻓度字段,⽤于记录该元素的⻓度或前⼀个元素到当前元素的偏移量。 • ‘one’, ‘two’: 实际的列表元素,它们被连续地存储在压缩列表中。 优势 内存利⽤率⾼,因为元素是连续存储的,没有额外的指针开销。 对于⼩列表,操作速度可以很快,因为所有数据都在⼀个连续的内存块中。 双向链表 当列表的元素数量较多或者元素较⼤时,Redis会选择使⽤双向链表作为底层实现。双向链表中的每个节点都保存了前⼀个节点和后⼀个节点的指针,这使得在列表的任何 位置插⼊或删除元素都变得相对容易。 优势 可以在O(1)时间复杂度内完成在列表头部或尾部的元素插⼊和删除。 当需要遍历列表时,可以从头部或尾部开始,沿着节点的指针依次访问。

3.hash的底层实现:Redis中的字典与压缩列表

Redis的哈希(Hashes)类型允许⽤户在单个键中存储多个字段和对应的值。为了⾼效地⽀持这种数据结构,Redis在底层使⽤了两种主要的数据结构来实现哈希:字典 (也称为哈希表)和压缩列表。 压缩列表 当哈希中的字段和值较少且较⼩时,Redis会使⽤压缩列表作为底层实现来节省内存。 内存利⽤率⾼,因为字段和值是连续存储的,没有额外的指针和元数据开销。 • 对于⼩哈希,操作速度可以很快,因为所有数据都在⼀个连续的内存块中。 字典( HASH 表) 当哈希中的字段和值较多或者较⼤时,Redis会选择使⽤字典作为底层实现。字典是⼀种通过键(在Redis哈希中是字段)来直接访问值的数据结构,它能够在平均情况下提供O(1)时间复杂 度的查找、插⼊和删除操作。 优势 提供了快速的字段查找、插⼊和删除操作。

哈希表的扩容机制可以保持较低的哈希冲突率,从⽽保证操作的效率。

4. 集合的底层实现:整数集合和字典

Redis的集合(Sets)是⼀个⽆序的、元素不重复的集合。为了⾼效地⽀持这种数据结构及其操作,Redis在底层使⽤了两种主要的数据结构:整数集合(intset)和字典 (hashtable)。 优势 • 内存利⽤率⾼:整数集合将整数紧密地存储在⼀个连续的内存块中,没有额外的指针或元数据开销。 • 操作速度快:对于整数集合中的元素,Redis可以直接通过数组索引访问,这使得查找、添加和删除整数的操作⾮常快速。 • 然⽽,整数集合也有其局限性。由于它要求集合中的元素必须是整数,并且元素数量较少,因此在处理⾮整数元素或⼤量元素时,整数集合可能不是最优的选择。 有序集合的底层实现:跳表和压缩列表 Redis的有序集合(Sorted Sets)是⼀个有序的、元素不重复的集合,其中每个元素都关联了⼀个分数(score)。为了实现这种数据结构及其相关操作的⾼效性,Redis在底层主 要使⽤了两种数据结构:压缩列表(ziplist)和跳表(skiplist)。 跳表(skiplist) 当有序集合的元素数量较多或元素的⼤⼩较⼤时,Redis会使⽤跳表作为底层实现。跳表是⼀种多层的有序链表,它通过维护多个层次的指针来加快查找、插⼊和删除操作的速度。 查找效率⾼:通过维护多个层次的指针,跳表可以在平均情况下提供O(log N)时间复杂度的查找操作,其中N是元素的数量。 • 插⼊和删除操作快速:跳表的插⼊和删除操作只需要局部地调整指针,⽽不需要移动⼤量的数据。 • ⽀持范围查询:跳表可以⽅便地⽀持按照分数范围查询元素的操作

标签:redis,元素,Redis,列表,集合,哈希,字符串
From: https://blog.csdn.net/weixin_69039908/article/details/138509826

相关文章

  • Redis实现延迟任务
    @DatapublicclassTaskimplementsSerializable{/***任务id*/privateLongtaskId;/***类型*/privateIntegertaskType;/***优先级*/privateIntegerpriority;/***执行id*/......
  • Redis中设置增量缓存,减少对数据库的交互查询;启动@Async;异步线程
    //当属于这个分支的报文传入调用processMessage方法if((newJSONObject(dataMessage).optString("documentStatus")).equals("carWeizi_redis_service")){processMessage(dataMessage);}//processMessage中先把增量数据插入数据库,同时缓存redispublic......
  • RedisTemplate 中序列化方式辨析
    在SpringDataRedis中,RedisTemplate是操作Redis的核心类,它提供了丰富的API来与Redis进行交互。由于Redis是一个键值存储系统,它存储的是字节序列,因此在使用RedisTemplate时,需要指定键(Key)和值(Value)的序列化方式。不同的序列化方式适用于不同的场景。下面将详细介绍几种序列......
  • redis 5 安装配置以及脚本
     redis6.2安装配置以及脚本(147)  wgethttp://download.redis.io/releases/redis-6.2.14.tar.gz tar-xfredis-5.0.10.tar.gz-C/usr/local/ cd/usr/local/redis-5.0.10&&make ...... vimredis.conf daemonizeyesbind127.0.0.1192.168.1.252 ......
  • 实战篇——SSRF漏洞Redis反弹shell实战
    实战篇——SSRF漏洞Redis反弹shell实战SSRF之Redis实战上一章中利用file伪协议实现了内网的主机探测,发现存在192.168.118.151,对其进行端口探测:可见开放了6379端口,结合响应判断为Redis服务。而Redis存在未授权访问漏洞,可以利用该漏洞实现信息泄露、数据删除以及反弹shell,下面......
  • redis-benchmark压力测试
    01测试-redis-benchmark压力测试redis自带有redis-benchmark工具做压力测试,经常用来测试新版本,新特性对基准测试性能的影响。参数场景变化下的性能状况。主要参数: -h<hostname>   服务器地址(default127.0.0.1) -p<port>     端口(default6379) -s<so......
  • java Redission 分布式锁的使用
    在微服务的场景下,一个应用会部署多个实例,在一些业务场景中,需要保证同一时间多个线程只能有一个线程操作资源,分布式锁可以实现这一需求。JAVA中,Redission分布式锁是基于Redis实现的分布式锁,使用简单,只需要关注业务场景和使用到的接口即可。引入依赖<!--https://mvnreposito......
  • Redis是单线程还是多线程的?
    讲Redis是单线程还是多线程的需要根据redis各版本的一个变化,在Redis的老版本中,redis是单线程的,redis的数据处理读写命令都是由一个线程完成,并且速度很快,是因为redis的数据都是存储在内存中的,避免了磁盘I/O的瓶颈,有通过非阻塞IO和事件驱动模型,使得单线程依旧可以处理大量的数据......
  • Windows的Redis安装及执行文件的路径修改
    一、下载redis的zip文件下载地址:https://github.com/tporadowski/redis/releases这里我们下载Redis-x64-xxx.zip压缩包到C盘,解压至重新命名为redis的文件夹。二、命令配置1.打开redis文件夹,在路径上输入cmd进入命令窗口(也可以打开一个cmd窗口使用cd命令切换目录......
  • Redis基础教程(十八):Redis管道技术
    ......