redis基础篇

1. 什么是redis?

redis的全称是REmote DIctionary Service,翻译过来就是远程词典服务

2. SQL与NOSQL

sql(关系型数据库):

  1. 以表格的形式存储行数据
  2. 存储格式需要与表结构相同
  3. 表之间存在关联
  4. 支持关联查询
  5. 事务来保证数据一致性

但是在数据量很大时,修改表结构非常困难。关系型数据库需要将数据持久化到磁盘,频繁IO操作在高并发场景下读写压力大,由此引出NOSQL

nosql(非关系型数据库):

  1. 存储非机构化数据
  2. 表之间没有关联
  3. 支持海量存储和高并发读写

redis就是nosql的一种

3. redis特性

要了解redis特性,我们通过几个问题来寻找答案

  1. 为什么要把数据放到内存中?
    1)因为内存中查询速度更快 10w QPS
    2)减少数据库压力
  2. 如果是用内存作为缓存,为什么不会HashMap或者Memcached?
    1)Memcache 只有简单的KV存储结构,redis有更丰富的数据类型
    2)支持多种编程语言
    3)功能丰富:持久化机制、内存淘汰机制、事务、发布订阅、pipeline、lua脚本
    4)支持集群

4. redis存储结构

在这里插入图片描述
Redis 内部使用一个 redisObject 对象来表示所有的 key 和 value。

  1. type :代表一个 value 对象具体是何种数据类型。

  2. encoding :是不同数据类型在 redis 内部的存储方式,比如:type=string 代表 value 存储的是一个普通字符串,那么对应的 encoding 可以是 raw 或者是 int,如果是 int 则代表实际 redis 内部是按数值型类存储和表示这个字符串的,当然前提是这个字符串本身可以用数值表示,比如:“123” "456"这样的字符串。

  3. vm 字段:只有打开了 Redis 的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的。 Redis 使用 redisObject 来表示所有的 key/value 数据是比较浪费内存的,当然这些内存管理成本的付出主要也是为了给 Redis 不同数据类型提供一个统一的管理接口,实际作者也提供了多种方法帮助我们尽量节省内存使用。

5. redis支持的数据类型

String、Hash、Set、ZSet、List、HyperLogLog(基数统计)、Geo(地理位置)、Streams
操作可以在redis官网查看http://www.redis.cn/commands.html

5.1. String

5.1.1. String Encoding

String可以用来存INT、float(单精度浮点数)、String(字符串)

字符串所使用的encoding一共有3种

int,存储8个字节的长整型(2^63-1)
embstr,存储小于44字节的字符串,在redis3.0和3.2版本之间,将39个字节改为44个字节
raw,存储大于44字节的字符串

类型转换

  1. int不再是正数 >>> raw
  2. int超过long的范围(2^63-1) >>> embstr
  3. embstr长度超过44 >>> raw
  4. 修改来embstr,就会编程raw,因为embstr是不可修改的
  5. 转换过程不可逆
5.1.2. 应用场景

缓存热点数据、报表数据等、分布式Session、使用setnx实现分布式锁、incrby实现全局id、计数器、限流,通过incr递增,超过次数返回false

5.2 Hash

  1. Hash用来存储多个无序的键值对,最大存储数量为2^32-1
  2. Hash本身是一个KV存储结构
  3. 由最低层到最高层,是数组+链表的结构

在这里插入图片描述
简单理解,不需要背。Hash和java中hashmap一样可以扩容,也可以缩容

Hash底层可以使用两种数据结构实现

ziplist:OBJ_ENCODING_ZIPLIST(压缩列表)
hashtable:OBJ_ENCODING_HT(哈希表)

结构

ziplist是由连续内存块组成的双向链表,它不存在指向上一个/下一个节点的指针,而是存储上一个节点长度和当前节点的长度

5.2.1 Encoding
ZIP_STR_06B(0<<6) //长度小于等于63字节
ZIP_STR_14B(1<<6) //长度小于等于16383字节
ZIP_STR_32B(2<<6) //长度小于等于4294967295字节

满足以下两个条件时使用ziplist存储

  1. 哈希对象保存的键值对数量<512个
  2. 所有的键值对的键和值字符串长度都<64byte

参数通过redis.conf可修改,如果任何一个不满足,则结构会转换成hashtable

5.2.2. 应用场景

可以用String的地方都可以使用Hash。Hash可以更直观的存储对象

5.3 List

存储字符串,从左到右。元素可以重复,最大存储数量为2^32-1

List底层可以有3数据结构实现。早期版本中,数据量小时用ziplist,到达临界值时转换为linkedlist进行存储。3.2版本之后,统一使用quickList存储。

  1. linkedlist(双端链表)节点带有prev、next指针、head指针和tail指针,获取前置节点、后置节点、表头节点和表尾节点的复杂度都是O(1)。len属性获取节点数量也为O(1)。与双端链表相比,压缩列表可以节省内存空间,但是进行修改或增删操作时,复杂度较高;因此当节点数量较少时,可以使用压缩列表;但是节点数量多时,还是使用双端链表划算。在这里插入图片描述
  2. ziplist(压缩列表)
    当一个列表键只包含少量列表项,且是小整数值或长度比较短的字符串时,那么redis
    就使用ziplist(压缩列表)来做列表键的底层实现。ziplist是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块(而不是像双端链表一样每个节点是指针)组成的顺序型数据结构;具体结构相对比较复杂
  3. quickList 它是 zipList 和 linkedList 的混合体。quickList存储了一个双向链表,每一个节点都是一个ziplist
    在这里插入图片描述
    quicklist 默认的压缩深度是 0,也就是不压缩。为了支持快速的 push/pop 操作,quicklist 的首尾两个 ziplist 不压缩,此时深度就是 1。为了进一步节约空间,Redis 还会对 ziplist 进行压缩存储,使用 LZF 算法压缩。
5.3.1. 应用场景
  1. 存储有序内容的场景,存储数据列表
  2. 队列/栈,使用阻塞弹出,blpop,rpush

5.4 Set

Set存储String类型的无序集合,最大存储数量2^32-1

5.4.1. 存储
  1. redis使用intset或hashtable存储set,如果元素都是整型,就用intset。否则用hashtable,如果元素超过512个,也会变成hashtable
  2. 可通过redis.conf修改
  3. 数据存储在key中,value存null
5.4.2. 应用场景

抽奖,通过spop随机取数;差集、交集、并集

5.5 ZSet 有序集合

sorted set存储有序的元素。每个元素有个score,安装score从小到大排名。score相同时,按照key的ASCII码排序。

5.5.1. 存储

默认使用ziplist,如果元素数量大于等于128个,或任意长度大于等于64byte时,使用skiplist+dict存储

5.5.2. skiplist跳表

比如现在有个list,3->7->11->19->22。如果现在要插入一条数据,只能进行遍历然后插入。假设我们每相邻的两个节点中的一个节点进行改变,该节点多一个指针指向下下个节点,这样新的链表节点就只有原来的一半。这样查找时,就可以根据新链表去查,当查找到比当前数大时,再查询小节点。这就是跳跃表

其余类型不常用,就不说了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值