Redis笔记.md

Posted by lizhao on 07-09,2019

Redis

[toc]

概述

数据库分类

  • 关系型数据库

    MySQL,Oracle

  • NoSQL数据库
    • 键值(Key-Value)存储数据库,Redis
    • 列存储数据库,MonetDB
    • 文档型数据库,MongoDB
    • 图形(Graph)数据库

Redis

诞生

当时作者 Salvatore(塞尔瓦托)有这么一个需求,就是多个网站不断向服务器发送页面,而服务器需要为每个网站保存一定数量的最新页面记录,同时通过网页将数据实时给用户看到。但是无论 Salvatore如何优化,都很难在关系数据库里让小虚拟机处理大负荷的负载。最终他打算自己写一个内存数据库,能对列表的两端执行常数时间复杂度的弹出和推入操作,并加上子进程的持久化操作,于是 Redis 就诞生了。
到现在,使用的人数越来越多,Redis也越来越完善了。

优点

  1. 速度快。官方给出的数据是 10 万次ops(Operation per second,每秒操作数)的读写,这主要归功于这些数据都存在于内存中、单线程。
  2. 可设置持久化。Redis的持久化可以保证将内存中的数据每隔一段时间就保存于磁盘中,重启的时候会再次加载到内存。
  3. 支持多种数据结构。分别支持哈希、集合、list等。
  4. 支持多种编程语言。支持Java、PHP、Python、Ruby、Lua、Nodejs。
  5. 功能丰富。如发布订阅、Lua 脚本、事务、Pipeline(管道,即当指令到达一定数量后,客户端才会执行)。
  6. 简单。开源,不依赖外部库、单线程、只有 23000 行 Code。
  7. 高可用和分布式。Redis-Sentinel(v2.8)支持高可用,Redis-Cluster(v3.0)支持分布式。

业务场景

缓存系统

在DB和程序间增加一层redis

计数器

比如一个系统在某个时间段里面访问的次数

消息队列系统
排行榜及相关问题

store set,当数据量庞大的时候,优势明显

社交网络、聊天

即发布(Publish)与订阅(Subscribe)

基本使用

内部数据结构

redisObject

#define LRU_BITS 24
#define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) /* Max value of obj->lru */
#define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */

typedef struct redisObject {
    //对象的数据类型,占4bits,共5种类型
    unsigned type:4;        
    //对象的编码类型,占4bits,共10种类型
    unsigned encoding:4;

    //least recently used
    //实用LRU算法计算相对server.lruclock的LRU时间
    unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */

    //引用计数
    int refcount;

    //指向底层数据实现的指针
    void *ptr;
} robj;

//type的占5种类型:
/* Object types */
#define OBJ_STRING 0    //字符串对象
#define OBJ_LIST 1      //列表对象
#define OBJ_SET 2       //集合对象
#define OBJ_ZSET 3      //有序集合对象
#define OBJ_HASH 4      //哈希对象

/* Objects encoding. Some kind of objects like Strings and Hashes can be
 * internally represented in multiple ways. The 'encoding' field of the object
 * is set to one of this fields for this object. */
// encoding 的10种类型
#define OBJ_ENCODING_RAW 0     /* Raw representation */     //原始表示方式,字符串对象是简单动态字符串
#define OBJ_ENCODING_INT 1     /* Encoded as integer */         //long类型的整数
#define OBJ_ENCODING_HT 2      /* Encoded as hash table */      //字典
#define OBJ_ENCODING_ZIPMAP 3  /* Encoded as zipmap */          //不在使用
#define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */  //双端链表,不在使用
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */         //压缩列表
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */          //整数集合
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */      //跳跃表和字典
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */   //embstr编码的简单动态字符串
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */   //由压缩列表组成的双向列表-->快速列表

字符串 String

GET、SET 和 DEL

INCR、DECR、INCRBY、DECRBY

  • INCR key:就是 key 自增 1,不存在,自增后 get(key)=1;
  • DECR key:就是 key 自减 1,不存在,自减后返回 -1;
  • INCRBY key k:自增 k ,不存在,则返回 k;
  • DECRBY key k:自减 k 。

SET、SETNX、SET xx

  • SET key value:不管 key 是否存在,都设置;
  • SETNX key value:key 不存在,才设置(相当于 add);
  • SET key value xx:key 存在,才设置(相当于 update)。

MGET、MSET

  • MGET key1 key2 key3 ...:批量获取 key,原子操作;
  • MSET key1 val2 key2 val2 key3 val3:批量设置 key-value。

GETSET、APPEND、STRLEN

  • GETSET key newvalue:set key newvalue 并返回旧的 value,旧的 value 会被删除;
  • APPEND key value:将 value 追加到旧的 value 上;
  • STRLEN key:返回字符串的长度(注意中文)。

INCRBYFLOAT、GETRANGE、SETRANGE

  • INCRBYFLOAT key 3.5:在 key 上追加对应的值 3.5;
  • GETRANGE key start end:获取字符串指定下标所有的值;
  • SETRANGE key index value:设置指定下标所有对应的值。

哈希 Hash

Hash 相当于 value 是一个Map,里面的所有属性我们都可以单独新增、修改或者删除,而不需要像字符串那样全部覆盖操作。

HGET、HSET、HGETALL

  • HGET key field:获取存储在哈希表中指定字段的值。
  • HSET key field value:将哈希表 key 中的字段 field 的值设为 value。
  • HGETALL key:获取在哈希表中指定 key 的所有字段和值,生产环境不常用。
127.0.0.1:6379>  HMSET runoobkey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000
OK
127.0.0.1:6379>  HGETALL runoobkey
1) "name"
2) "redis tutorial"
3) "description"
4) "redis basic commands for caching"
5) "likes"
6) "20"
7) "visitors"
8) "23000"

列表 List

List 是一种简单的字符串的集合,是有顺序的。

LPUSH、RPUSH、LPOP、RPOP、LRANGE。

  • LPUSH key value1 [value2]:将一个或多个值插入到列表头部;
  • RPUSH key value1 [value2]:在列表中添加一个或多个值;
  • LPOP key:移出并获取列表的第一个元素;
  • RPOP key:移除并获取列表最后一个元素;
  • LRANGE key start stop:获取列表指定范围内的元素。

集合 Set

Set 和 List 最大的不同是无序,Set 是没有顺序的。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

SADD、SCARD、SNENVERS、SPOP。

  • SADD key member1:向集合添加一个或多个成员;
  • SCARD key:获取集合的成员数;
  • SMEMBERS key:返回集合中的所有成员;
  • SPOP key:移除并返回集合中的一个随机元素。

有序集合 Sorted Set

ZADD、ZRANGE、ZREM、ZCARD

  • ZADD key score1 member1:向有序集合添加一个或多个成员,或者更新已存在成员的分数;
  • ZRANGE key start stop:通过索引区间返回有序集合成指定区间内的成员;
  • ZREM key member:移除有序集合中的一个或多个成员;
  • ZCARD key:获取有序集合的成员数。

发布订阅 Pub/Sub

在 Redis 中,你可以设定对某一个 key 值进行消息发布及消息订阅,当 key 的值进行了消息发布后,所有订阅它的客户端都会收到相应的消息,这类似于 QQ、微信。

事务 Transactions

  1. 将所有的命令整合到一起,相当于一个脚本,进行执行。
  2. 错误检查:
    • 语法错误,直接报错
    • 运行期间错误,继续往下执行,不支持回滚

方法集合