redis 报错
ERR hash value is not an integer
ERR hash value is not an integer
无论是为了面试,还是为了更好的使用 Redis,我们都应该对 Redis 为什么性能这么好进行学习。
我以前的理解:
Redis 采用 C++ 编写,语言层面具有优势。
Redis 使用单线程,避免了线程切换带来的开销。
相比于数据库的数据存储在硬盘,Redis 的数据都是加载到内存中的,速度非常快。
以前对于 Redis 的学习一直是故步自封的,其中很多东西都没有去深究。
今天,让我们一起对 Redis 进行更进一步的学习。
我们先来看一张监控图(上图,我们线上真实案例),Redis在满容有驱逐策略的情况下,Master/Slave 均有大量的Key驱逐淘汰,导致Master/Slave 主从不一致。
今天看到一篇介绍 redis 热点数据处理的文章,这段时间也遇到了类似的问题处理。
学习一下,看看能不能借鉴一下别人的方法,结合自己的应用场景来解决问题。
这篇文章,咱们来聊聊热点缓存的架构优化问题。
其实使用缓存集群的时候,最怕的就是热key、大value这两种情况,那啥叫热key大value呢?
简单来说,热key,就是你的缓存集群中的某个key瞬间被数万甚至十万的并发请求打爆。
大value,就是你的某个key对应的value可能有GB级的大小,导致查询value的时候导致网络相关的故障问题。
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型, 并将 SDS 用作 Redis 的默认字符串表示。
在 Redis 里面, C 字符串只会作为字符串字面量(string literal), 用在一些无须对字符串值进行修改的地方, 比如打印日志:
redisLog(REDIS_WARNING,"Redis is now ready to exit, bye bye...");
redis自2.8.0之后版本提供Keyspace Notifications功能,允许客户订阅Pub / Sub频道,以便以某种方式接收影响Redis数据集的事件。
可能收到的事件的例子如下:
所有影响给定键的命令。
所有接收LPUSH操作的密钥。
所有密钥在数据库中过期0。
因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果你的程序需要可靠事件通知(reliable notification of events), 那么目前的键空间通知可能并不适合你:当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件。
为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
在 Redis 中,带有生存时间的 key 被称为『易失的』(volatile)。
生存时间可以通过使用 DEL 命令来删除整个 key 来移除,或者被 SET 和 GETSET 命令覆写(overwrite),这意味着,如果一个命令只是修改(alter)一个带生存时间的 key 的值而不是用一个新的 key 值来代替(replace)它的话,那么生存时间不会被改变。
比如说,对一个 key 执行 INCR 命令,对一个列表进行 LPUSH 命令,或者对一个哈希表执行 HSET 命令,这类操作都不会修改 key 本身的生存时间。
Redis服务器默认会创建16个数据库。
Redis 中的每个数据库,都由一个 redis.h/redisDb 结构表示:
typedef struct redisDb {
// 保存着数据库以整数表示的号码
int id;
// 保存着数据库中的所有键值对数据
// 这个属性也被称为键空间(key space)
dict *dict;
// 保存着键的过期信息
dict *expires;
// 实现列表阻塞原语,如 BLPOP
// 在列表类型一章有详细的讨论
dict *blocking_keys;
dict *ready_keys;
// 用于实现 WATCH 命令
// 在事务章节有详细的讨论
dict *watched_keys;
} redisDb;
redis 默认有 16 个 db,编号为 0-15
各个 db 之间的操作是互不影响的。
当然也可以自行设置总数:
redis 配置文件中下面的参数来控制数据库总数:
/etc/redis/redis.conf 文件中,有个配置项
databases = 16