Redis 源码分析(一)

来源:互联网 发布:mac怎么修复磁盘权限 编辑:程序博客网 时间:2024/05/22 01:32

前言

最近一直在预研Redis内存库,下面写的主要是个人的理解,有什么不对地方欢迎大家指正,Redis是依据BSD协议发行的高性能Key-Value存储系统,通常被称为数据结构服务器。

他的值可以是字符串(string),哈希(map),链表(list),集合(sets)和有序集合(sorted sets)等。对于编程新手来说,Redis绝对是学习数据结构非常经典的资料。

下面是官方的解绍

Introduction to Redis

Redis is an open source, advanced key-value store. It is often referred to as adata structure server since keys can containstrings,hashes, lists, sets andsorted sets.

You can run atomic operations on these types, like appending to a string; incrementing the value in a hash; pushing to a list; computing set intersection, union and difference; orgetting the member with highest ranking in a sorted set.

In order to achieve its outstanding performance, Redis works with an in-memory dataset. Depending on your use case, you can persist it either bydumping the dataset to disk every once in a while, or byappending each command to a log.

Redis also supports trivial-to-setup master-slave replication, with very fast non-blocking first synchronization, auto-reconnection on net split and so forth.



先介绍下adlist.h/adlist.c

/* Node, List, and Iterator are the only data structures used currently. */typedef struct listNode {    struct listNode *prev;    struct listNode *next;    void *value;}listNode;typedef struct listIter {    listNode *next;    int direction;}listIter;typedef struct list {    listNode *head;    listNode *tail;    void *(*dup)(void *ptr);    void *(*free)(void *ptr);    int (*match)(void *ptr,void *key);    unsigned long len;} list;

listNode 节点下包含prev指针和next指针,说明它通过指针将节点进行双向链接。

list里面声明

/* Prototypes */list *listCreate(void);void listRelease(list *list);list *listAddNodeHead(list *list, void *value);list *listAddNodeTail(list *list, void *value);list *listInsertNode(list *list, listNode *old_node, void *value, int after);void listDelNode(list *list, listNode *node);listIter *listGetIterator(list *list, int direction);listNode *listNext(listIter *iter);void listReleaseIterator(listIter *iter);list *listDup(list *orig);listNode *listSearchKey(list *list, void *key);listNode *listIndex(list *list, long index);void listRewind(list *list, listIter *li);void listRewindTail(list *list, listIter *li);void listRotate(list *list);


下面引用一个对Redis list用途的总结

http://blog.csdn.net/gaogaoshan/article/details/41039581

常用命令:    lpush,rpush,lpop,rpop,lrange,BLPOP(阻塞版)等。应用场景:    Redis list的应用场景非常多,也是Redis最重要的数据结构之一。    我们可以轻松地实现最新消息排行等功能。    Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。实现方式:    Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。RPOPLPUSH source destination    命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:    将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。    将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。    如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。    一个典型的例子就是服务器的监控程序:它们需要在尽可能短的时间内,并行地检查一组网站,确保它们的可访问性。    redis.lpush "downstream_ips", "192.168.0.10"    redis.lpush "downstream_ips", "192.168.0.11"    redis.lpush "downstream_ips", "192.168.0.12"    redis.lpush "downstream_ips", "192.168.0.13"    Then:    next_ip = redis.rpoplpush "downstream_ips", "downstream_ips"BLPOP  假设现在有 job 、 command 和 request 三个列表,其中 job 不存在, command 和 request 都持有非空列表。考虑以下命令:  BLPOP job command request 30  #阻塞30秒,0的话就是无限期阻塞,job列表为空,被跳过,紧接着command 列表的第一个元素被弹出。  1) "command"                             # 弹出元素所属的列表  2) "update system..."                    # 弹出元素所属的值  为什么要阻塞版本的pop呢,主要是为了避免轮询。举个简单的例子如果我们用list来实现一个工作队列。执行任务的thread可以调用阻塞版本的pop去获取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回,也可以避免轮询带来的延迟。





0 0
原创粉丝点击