7.redis对象介绍(三)

1.类型检查与命令多态

redis中用于操作键的命令可以分为两种,一种是可以对任何类型的键执行的命令,比如del,expire,rename,type,object等;另一种是只能对特定类型的键执行,比如set,hset,lpop,rpush,sadd,zadd等等。

1.1 类型检查的实现

        为了确保只有制定类型的键才可以执行某些特定的命令,在执行一个命令前,会先检查输入键的类型是否正确。

        类型特定命令所进行的类型检查是通过redisObject结构的type属性来实现的:在执行一个命令前,服务器会先检查输入数据库键的值对象是否为执行命令所需的类型,是的话则执行,否则,拒绝执行,返回错误。

1.2 多态命令的实现

        redis除了会根据值对象的类型来判断键是否能执行指定命令之外,还会根据值对象的编码方式,选择正确的命令实现代码来执行。

        例如:当我们执行llen命令时,列表对象有ziplist和linkedlist两种编码可用,那么服务器会现根据对象的编码选择正确的llen命令实现,如果是ziplist编码,将使用ziplist函数来返回列表的长度;如果是linkedlist,程序将使用listlength函数来返回双端列表的长度。

2.内存回收

因为C语言并不具备自动内存回收的功能,所以redis在自己的对象系统中构建了一个引用计数来实现内存的回收机制。

每个对象的引用计数信息由redisobject结构的refcount属性记录,在创建一个对象时,引用计数的值会被初始化为1;当对象被一个新程序使用时,他的引用计数值会被增1;当对象不再被一个程序使用时,他的引用计数值会被减1,当对象的引用计数值变为0时,对象所占用的内存会被释放。

3.对象共享

        对象的引用计数属性除了用于实现引用计数内存回收之外,还带有对象共享的作用。例如:键A创建了一个包含整数值100的字符串对象作为值对象,这是键B也要创建一个同样保存了整数值100的字符串对象,那么服务器有以下两种做法:

  1. 为键B创建一个包含整数值100的字符串对象;
  2. 让键A和键B共享同一个字符串对象;

在redis中,让多个键共享同一个值对象需要执行以下两个步骤:

  1. 将数据库键的值指针指向一个现有的值对象;
  2. 将被共享的值对象的引用计数加1;

目前来说,redis会在初始化服务器时,创建一万个字符串对象,这些对象包含了从0到9999的所有整数值,当需要用到时,服务器会使用这些共享对象,而不是新创建对象;另外,共享对象不单单只有字符串键可以使用,那些在数据结构中嵌套了字符串对象的对象(如列表,哈希对象,集合对象,有序集合)都可以使用这些共享对象;

为什么redis只共享整数型字符串对象?

因为当服务器考虑将一个共享对象设置为键的值对象时,程序需要先检查给定的共享对象和键想创建的目标对象是否完全相同,一个共享对象越复杂,验证两个对象是否相同就会越复杂,消耗的cpu时间越多。

4.对象的空转时长

        除了前面介绍的type、encoding、ptr、refcount四个属性之外,redisObject结构还包含一个属性lru,该属性记录了对象最后一次被命令程序访问的时间;Object idletime命令可以打印出给定键的空转时长,这一空转时长就是通过当前时间减去键的值对象的lru时间计算得出的。

        object idletime命令不会修改值对象lru属性;

        空转时长的另外一个作用:当服务器打卡了maxmemory选项,并且服务器用于内存回收的算法为volatile-lru或者allkeys-lru,那么服务器占用的内存数超过了maxmemory选项所设置的上限值时,空转时长较高的那部分键会被优先释放。

`org.springframework.data.redis.connection.RedisConnection` 接口是 Spring Data Redis 框架中用于与 Redis 服务器建立连接并执行操作的核心接口之一。`keyCommands()` 方法是该接口提供的一个重要方法,用于获取 `RedisKeyCommands` 类型的对象,该对象封装了一系列与 Redis 键操作相关的命令。 ### 方法签名 ```java RedisKeyCommands keyCommands(); ``` ### 方法功能 `keyCommands()` 方法的主要功能是返回一个 `RedisKeyCommands` 实例,该实例提供了对 Redis 键的各种操作方法,例如键的创建、删除、查询、过期设置等。通过这个方法,开发者可以方便地操作 Redis 中的键,而不需要直接与底层的 Redis 连接进行交互。 ### 使用示例 以下是一个简单的示例,展示了如何使用 `keyCommands()` 方法来操作 Redis 键: ```java import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisKeyCommands; // 假设已经有一个 RedisConnectionFactory 实例 RedisConnectionFactory connectionFactory; // 获取 Redis 连接 RedisConnection connection = connectionFactory.getConnection(); // 获取 RedisKeyCommands 实例 RedisKeyCommands keyCommands = connection.keyCommands(); // 设置一个键值对 keyCommands.set("myKey".getBytes(), "myValue".getBytes()); // 检查键是否存在 Boolean exists = keyCommands.exists("myKey".getBytes()); System.out.println("Key exists: " + exists); // 删除键 keyCommands.del("myKey".getBytes()); // 再次检查键是否存在 exists = keyCommands.exists("myKey".getBytes()); System.out.println("Key exists after deletion: " + exists); // 关闭连接 connection.close(); ``` ### 注意事项 - 在使用 `keyCommands()` 方法时,需要确保已经正确配置了 Redis 连接工厂,并且能够成功连接到 Redis 服务器。 - 操作完成后,应该及时关闭 Redis 连接,以释放资源。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值