redis学习笔记

摘录些nosqlfans上看的资源(http://blog.nosqlfan.com/html/3537.html),用了一年了,只会安装、启动和get set,真的不好意思说会redis

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统,他为VMWare 公司工作,主要就是进行Redis的开发。 Blizzard (暴雪)使用8节点的Redis来为 WoW (魔兽争霸)提供Avatar服务。

一、redis启动初探

http://pauladamsmith.com/blog/2011/03/redis_get_set.html 原文 

  1. redis 启动图  
  1.  redisServer是main函数启动的redis实例,包含属性: -general server state -statistics -configuration from config file -replication -sort parameters -virtual memory config, state, I/O threads, & stats -zip structure -event loop helpers ,事件模型默认是epoll on Linux, kqueue on BSD, 若没有开启则使用select方式 -pub/sub  append-only file (AOF) ,(追加式的操作日志记录,appendonly yes 打开日志),作用和rdb文件类似,用于保存上次redis 会话数据
  2. redis请求处理模型:

Redis starts up by initializing a global server state variable, and reading in an optional configuration file to override any defaults. It sets up a global command table that connects command names with the actual function that implements the command. It creates an event loop using the best available underlying system library for event/readiness notification, and registers a handler function for when there is a new client socket connection to accept. It also registers a periodic (i.e., time-based) event handler for dealing with cron-like tasks like key expiry that need to be addressed outside the regular client-handling path. Once a client has connected, a function is registered on the event loop for being notified when the client has data to be read (i.e., a query for a command). The client’s query is parsed and a command handler is called to execute the command and write the response back to the client (the writing of data to the client is also handled by the event-notification loop). The client object is reset and server is ready to process more queries.

二、 使用gdb分析get set command

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。  http://pauladamsmith.com/blog/2011/03/redis_get_set.html  介绍了使用gdb加断点跟踪GET和SET

redis-cli  使用 redisContext封装相关连接状态,hiredis.h(deps目录)定义了 redisContext, obuf 字段存放redis-cli输入的原生命令

redis_client.get('users:1234')  和 命令行指令 get users:1234 一样,会发送  *2\r\n$3\r\nget\r\n$10\r\nusers:1234\r\n   字节串到服务器 

服务器端redis-server  为每个客户端创建buffer,将字节流扩展至buffer中,执行方法readQueryFromClient 接收数据。  然后根据请求方式 lookupCommand(c->argv[0]->ptr),

从command的定义中可找到get方法

 

struct redisCommand readonlyCommandTable[] = {
{"get",getCommand,2,0,NULL,1,1,1}, 

 getCommand 是getGenericCommand方法的封装,找到对应方法后,执行,从数据库中查找key对应的value:

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

redis使用自己的hash table在内存中存储key-value对,在db对象中,dict字段指向当前库的hash值(redis一个实例可以有16个库)

redis调用dictFind方法(dict.c)在数据库的hashtable中查找对应值。

SET流程与此类似,调用dictAdd方法设置key-value对。

三、redis源码分析

(1)redis replication (http://www.hoterran.info/redis_replication)

(2)redis 持久化(http://www.hoterran.info/redis_persistence)

redis有全量(save/bgsave)和增量(aof)的持久化命令。 全量的原理就是遍历里所有的DB,在每个bucket,读取链表的key和value并写入dump.rdb文件(rdb.c 405)。 save命令直接调度rdbSave函数,这会阻塞主线程的工作,通常我们使用bgsave。

sync:当master接收到slave发来的该命令的时候,会执行rdbSaveBackground

增量备份就是aof,原理有点类似redo log。每次执行命令后如出现数据变化,会调用feedAppendOnlyFile,把数据写到server.aofbuf里。aof最大的问题就是随着时间append file会变的很大,所以我们需要bgrewriteaof命令重新整理文件,只保留最新的kv数据。

(3)redis rehash(http://www.yiihsia.com/2011/04/redis源码分析-如何rehash/)

rehash有2种工作模式 lazy rehashing:在每次对dict进行操作的时候执行一个slot的rehash active rehashing:每100ms里面使用1ms时间进行rehash。 什么时候dict做扩容? 在数据插入的时候会调用dictKeyIndex,该方法里会调用_dictExpandIfNeeded,判断dict是否需要rehash,当dict中元素大于桶的个数时,调用dictExpand扩展hash。dictExpand的工作主要是初始化hash表,默认是扩大两倍(并不单纯是桶的两倍),然后赋值给ht[1],然后状态改为rehashing,此时该dict开始rehashing 四、redis基本结构

  • 值类型: 二进制安全的 字符串 string 二进制安全的 字符串列表 list of string 二进制安全的 字符串集合 set of string,换言之:它是一组无重复未排序的element。可以把它看成Ruby中的 hash–其key等于element,value都等于’true‘。 有序集合sorted set of string,类似于集合set,但其中每个元素都和一个浮点数score(评分)关联。element根据score排序。可以把它看成Ruby中的 hash–其key等于element,value等于score,但元素总是按score的顺序排列,无需额外的排序操作。  
  • 键类型: Redis key值是二进制安全的,这意味着可以用任何二进制序列作为key值,从形如”foo”的简单字符串到一个JPEG文件的内容都可以。空字符串也是有效key值。
  • 列表:   LPUSH 命令可向list的左边(头部)添加一个新元素,而RPUSH命令可向list的右边(尾部)添加一个新元素。最后LRANGE 命令可从list中取出一定范围的元素,   如 lrange messages 0 2
  • 集合 Redis集合是未排序的集合,其元素是二进制安全的字符串。SADD命令可以向集合添加一个新元素。和sets相关的操作也有许多,比如检测某个元素是否存在,以及实现交集,并集,差集等等。sadd添加 smembers获取所有 sismember 监测是否是成员集合 子交并补等操作 redis 127.0.0.1:6379> SINTER birds mammals 1) "bat" redis 127.0.0.1:6379> SUNION birds mammals 1) "crow" 2) "bat" 3) "human" 4) "pigeon" 5) "dog" redis 127.0.0.1:6379> SDIFF birds mammals 1) "crow" 2) "pigeon"
  • 有序集合 有序集合 带有关联的score,以及一个类似LRANGE的操作可以返回有序元素,ZRANGE  ZREVRANGE 命令 可作用于有序集合 。 有序集合从某种程度上说是SQL世界的索引在Redis中的等价物 zadd hackers 1940 "Alan Kay"  zrange hackers 0 -1 zrevrange hackers 0 -1 zrangebyscore hackers -inf 1950    #获取所有1950年之前出生的人 zremrangebyscore hackers 1940 1960  #删除生日介于1940到1960年之间的黑客。
  • Hash类型 Redis能够存储key对多个属性的数据(比如user1.uname user1.passwd) redis 127.0.0.1:6379> HKEYS student 1) "name" 2) "age" 3) "sex" redis 127.0.0.1:6379> HVALS student 1) "Ganesh" 2) "30" 3) "Male" redis 127.0.0.1:6379> HGETALL student 1) "name" 2) "Ganesh" 3) "age" 4) "30" 5) "sex" 6) "Male" redis 127.0.0.1:6379> HDEL student sex (integer) 1 redis 127.0.0.1:6379> HGETALL student 1) "name" 2) "Ganesh" 3) "age" 4) "30" Hash数据结构能够批量修改和获取 redis 127.0.0.1:6379> HMSET kid name Akshi age 2 sex Female OK redis 127.0.0.1:6379> HMGET kid name age sex 1) "Akshi" 2) "2" 3) "Female" 更多可参考 redis命令 http://redis.io/commands/ 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏LhWorld哥陪你聊算法

【Linux篇】--awk的使用

awk是一个强大的文本分析工具。相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。 简单来说awk就是把文件逐行的读入,(空格...

14720
来自专栏xingoo, 一个梦想做发明家的程序员

【Spring开发】—— AOP之方法级拦截

前言: 前面介绍了Spring的核心模块以及相关的依赖注入等概念。这篇讲解一下spring的另一个重点,AOP面向切面编程。   说道AOP不得不提到几...

21580
来自专栏cmazxiaoma的架构师之路

【分布式架构之旅】Redis入门

27430
来自专栏阿杜的世界

Spring中bean的scope

Spring容器中的bean具备不同的scope,最开始只有singleton和prototype,但是在2.0之后,又引入了三种类型:request、sess...

9720
来自专栏编码小白

ofbiz中FreeMarkerWorker的makeConfiguration方法

            这个方法是说明了为什么在ftl中可以使用一些java方法             1.代码展示 public static Confi...

38070
来自专栏java一日一条

2015年Java开发岗位面试题归类

3. 说说你知道的几个Java集合类:list、set、queue、map实现类咯。。。

10410
来自专栏Kirito的技术分享

JAVA 拾遗--Future 模式与 Promise 模式

写这篇文章的动机,是缘起于微信闲聊群的一场讨论,粗略整理下,主要涉及了以下几个具体的问题: 同步,异步,阻塞,非阻塞的关联及区别。 JAVA 中有 callb...

3K100
来自专栏Java架构沉思录

Mybatis插件机制详解

Mybatis采用责任链模式,通过动态代理组织多个插件(拦截器),通过这些插件可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Myba...

27210
来自专栏犀利豆的技术空间

徒手撸框架--实现 RPC 远程调用

微服务已经是每个互联网开发者必须掌握的一项技术。而 RPC 框架,是构成微服务最重要的组成部分之一。趁最近有时间。又看了看 dubbo 的源码。dubbo 为了...

16620
来自专栏Java 源码分析

Java之StringBuffer

1.存储: append(data) 添加在最后 insert(index,data) 在制定位置添加2.删除: delete(start,end) 删除...

33260

扫码关注云+社区

领取腾讯云代金券