redis DB操作

数据库操作

1)  REDIS是全部由KEY和VALUE值构成,对数据库的增删改查操作都是基于在通过key 映射到哈希槽 然后通过哈希槽进行单向链式遍历 查找到value和具体的key。

同样 在查看大师写的源码时可以说是一种很好借鉴:

这里所有的操作已经主体源码引用都是zai redis/src/db.c下进行的:

robj *lookupKey(redisDb *db, robj *key) {
    dictEntry *de = dictFind(db->dict,key->ptr);
if (de) {
        robj *val = dictGetVal(de);
/* Update the access time for the ageing algorithm.
         * Don‘t do it if we have a saving child, as this will trigger
         * a copy on write madness. */
if (server.rdb_child_pid == -1 && server.aof_child_pid == -1)
            val->lru = server.lruclock;
return val;
    } else {
return NULL;
    }
}

lookforKey: 根据key 来寻找value

robj 是redis提出的一个抽象对象类【当然是用C写的  但是这是一层抽象层】含有一系列redis所需要的参数数据,在这里 通过dictFind查找之后就可以得到dicEntry 【就是dic最基本的元素/含有key value指针】 就会构造出一个robj需要的值。

中间的rdb_child_pid和aof_child_pid是服务器做持久化缓存的2种进制,redis通过cow策略来做,如果有正在做持久化的一个动作,就会去设置lru变量  这个等到后面持久化等部分会详细介绍。

在这里: 有一个细节点: void *val 是dicEntry一个变量,怎么robj *val 就可以得到dicGetVal(de)呢  而且还能顺利的得到val的lru值呢?

因为所有写操作 都是通过robj对象写进去的 只不过在dicEntry定义void*类型。

这个操作是最基本的  不管做增删改查 都需要调用lookforKey

robj *lookupKeyRead(redisDb *db, robj *key) {
    robj *val;
    expireIfNeeded(db,key);
    val = lookupKey(db,key);
if (val == NULL)
        server.stat_keyspace_misses++;
else
        server.stat_keyspace_hits++;
return val;
}

redis是一个支持键值存在长度的数据库,所以呢  在写和读的上层操作时 都需要做一个expireIfNeed的操作。这个操作就是看看Key到期了没  这个Key的时间热度 在后面的部分也详细做分析

stat_keyspace_misss 就是统计整个服务器的Key不存在的总数量,这些数据给server做出相应的决策  在后面同样要进行分析server一系列的数据

robj *lookupKeyReadOrReply(redisClient *c, robj *key, robj *reply) {
    robj *o = lookupKeyRead(c->db, key);
if (!o) addReply(c,reply);
return o;
}

这里是REDISClient做抽象的 如果robj 不是NULL,那么都会给客户端返回一个结果 这个结果都是统一用addReply函数来实现

void dbAdd(redisDb *db, robj *key, robj *val) {
    sds copy = sdsdup(key->ptr);
int retval = dictAdd(db->dict, copy, val);
    redisAssertWithInfo(NULL,key,retval == REDIS_OK);
}

这个函数就是添加操作。调用dic里的添加函数,可以看出redis所有的redis都是一个字符串构成, sds 是char*。所以这里存的copy就是一个指向字符串的指针。

注意点: 这里的Key是复制一份到copy中的,为什么这么做,如果主调程序删除了Key空间,但是我按照功能来讲:redis是一个存储Key和value的结构,不管主调程序是否释放空间,我都应该存在 只有当用户发出删除命令或者达到时间限制命令才会释放key空间。这里的sdsdup是一个复制一个字符串的过程。

处理修改KEY
  1. /*-----------------------------------------------------------------------------
  2. * Hooks for key space changes.
  3. *
  4. * Every time a key in the database is modified the function
  5. * signalModifiedKey() is called.
  6. *
  7. * Every time a DB is flushed the function signalFlushDb() is called.
  8. *----------------------------------------------------------------------------*/
  9. void signalModifiedKey(redisDb *db, robj *key) {
  10. touchWatchedKey(db,key);
  11. }
  12. void signalFlushedDb(int dbid) {
  13. touchWatchedKeysOnFlush(dbid);
  14. }

这里先来看key  每当key被改变时,都会调用touchWatchedKey(db,key). 在redis每次做改 为什么会调用这个function呢?

以及touchWatchedKey的具体含义在哪里?

在事务部分可以看到 每当上层修改操作进行改这个key时 都会调用touchWatchedKey()  如果Key没有touched  进行正常的增删改

如果有的话,主调函数进行正常的增删改,只不过会做相应的redisClient的DIR改写

时间: 2024-10-13 00:11:34

redis DB操作的相关文章

php的redis 操作类,适用于单台或多台、多组redis服务器操作

redis 操作类,包括单台或多台.多组redis服务器操作,适用于业务复杂.高性能要求的 php web 应用. redis.php: <?php /* redis 操作类,适用于单台或多台.多组redis服务器操作 使用方法: 1.$rs=new mz_redis();$rs->load_config_file('redis_config1.php');$www=$rs->connect(1,true,0)==单台读连接,连接read_array第一个元素对应的redis服务器中的随

C#中使用Redis学习二 .NET4.5中使用redis hash操作

上一篇>> 摘要 上一篇讲述了安装redis客户端和服务器端,也大体地介绍了一下redis.本篇着重讲解.NET4.0 和 .NET4.5中如何使用redis和C# redis操作哈希表.并且会将封装的一些代码贴一下.在讲解的过程中,我打算结合redis操作命令一起叙述,算是作为对比吧.这样也能让读者清楚了解,所分装的代码对应的redis的哪一些操作命令. hash哈希表简介 如何在.NET4.0/4.5中安装redis组件? 在上一篇博文中,安装好的redis服务器端,要记得开启服务.然后再

Python-连接Redis并操作

首先开启redis的外连 [email protected]:~$ sudo vim /etc/redis/redis.conf 把bind 127.0.0.1这行注释掉 然后重启redis sudo /etc/init.d/redis-server restart 这样ubuntu的redis本机就可以连接了 连接并操作 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import redis r = redis.Redis(ho

Redis服务器操作

[Redis服务器操作] 1.TIME 返回当前服务器时间. 2.DBSIZE 返回当前数据库的 key 的数量. 3.LASTSAVE 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示. 4.BGSAVE 在后台异步(Asynchronously)保存当前数据库的数据到磁盘. BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出.

Redis 基础操作

[Redis 基础操作] 1.ECHO message. Returns message. 2.PHING Returns PONG if no argument is provided, otherwise return a copy of the argument as a bulk. This command is often used to test if a connection is still alive, or to measure latency. 3.SELECT index

zabbix监控redis DB key的总数量

一个简单监控redis DB的key数量,脚本如下: #!/bin/bash PORT='7010' HOST='192.168.33.33' echo `redis-cli -h ${HOST} -p ${PORT} <<EOF select 1 llen data1 EOF` > /usr/local/redis/script/redix.txt echo `awk '{print $2}' /usr/local/redis/script/redix.txt` exit 0 脚本实现

Redis 授权操作

[Redis 授权操作] AUTH password 通过设置配置文件中 requirepass 项的值(使用命令 CONFIG SET requirepass password ),可以使用密码来保护 Redis 服务器. 如果开启了密码保护的话,在每次连接 Redis 服务器之后,就要使用 AUTH 命令解锁,解锁之后才能使用其他 Redis 命令. 如果 AUTH 命令给定的密码 password 和配置文件中的密码相符的话,服务器会返回 OK 并开始接受命令输入. 另一方面,假如密码不匹

Redis Hash操作

[Redis Hash操作] 1.HSET key field value Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten. Return value Integer reply, specifically: 1 if fi

Redis 集合操作

[Redis 集合操作] 1.SCARD key 返回集合 key 的基数(集合中元素的数量). 2.SDIFFSTORE destination key [key ...] 这个命令的作用和 SDIFF 类似,但它将结果保存到 destination 集合,而不是简单地返回结果集. 如果 destination 集合已经存在,则将其覆盖. destination 可以是 key 本身. 3.SINTER key [key ...] 返回一个集合的全部成员,该集合是所有给定集合的交集. 不存在的