00.redis入门

[TOC]

redis是什么

官方解释:
redis 是一个开源的,内存中的K-V数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 redis内置了复制(replication),LUA脚本(Lua scripting),LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

redis是remote dictionary server的简写,这样可以明显地了解Redis的定位。redis简单来看就是一个内存中(运行时)的hashtable,所有的数据都在内存中,它支持最基础的put和get操作对hash表内的数据进行修改。这是它最为基础的功能,因为是基于内存,所以支持高效的读写(官方给出的数据为10w次/s的读写性能),很容易想到最常见的使用场景:缓存。另外因为它支持数据的持久化(有两种持久化策略),所以也可以作为nosql的解决方案。

除了基础的数据存取之外,redis支持分布式,所以可以构建分布式缓存和分布式的消息中间件以及分布式数据库,来提供高可用性。

redis的主要特性

  • 速度快
  • 数据存储在内存中
  • 基于键值对的数据结构服务器
  • 支持多种数据类型
  • 功能丰富,如复制、HyperLogLog、事务、发布订阅、持久化等
  • 简单稳定
  • 客户端支持大量的语言
  • 支持高可用和分布式

单线程架构

Redis服务是单线程的进程,底层是使用了IO多路复用模型来支撑高性能的内存数据库服务。

所有发送到redis的命令都会进入一个命令队列中,一个一个执行,所以如果某个命令执行了很久,就会影响整个redis的性能表现。

redis为什么这么快

官方给的redis的读写性能能够达到数万到数十万次每秒,How fast is Redis?,具体性能和系统以及硬件是相关的。

redis的性能很好有几个主要的原因:

  • 基于内存,和磁盘读写不是一个数量级
  • 使用C语言这个近操作系统的语言,有较好的执行性能
  • 单线程的架构设计,没有并发控制的开销
  • redis源码十分优秀
  • 使用epoll作为IO多路复用技术来实现NIO(NonBlocking IO)

Redis基于单线程模型,使用中一定要注意线程阻塞的情况。

redis使用场景

  • 缓存
  • 排行榜系统
  • 计数器应用
  • 社交网络
  • 消息队列

redis环境搭建

redis使用了很多操作系统的特性,且是基于Linux系统的,官方是不支持Windows系统的,Windows版本的是Windows团队开发的一个分支。

下载安装

wget http://download.redis.io/releases/redis-4.0.10.tar.gz  
tar xzf redis-4.0.10.tar.gz
cd redis-4.0.10
make && make install

安装成功后,redis相关运行文件在/usr/local/bin中。

[root@aliyun bin]# ll /usr/local/bin/
total 21872
-rwxr-xr-x 1 root root 2451088 Sep 22 16:19 redis-benchmark
-rwxr-xr-x 1 root root 5773320 Sep 22 16:19 redis-check-aof
-rwxr-xr-x 1 root root 5773320 Sep 22 16:19 redis-check-rdb
-rwxr-xr-x 1 root root 2617168 Sep 22 16:19 redis-cli
lrwxrwxrwx 1 root root      12 Sep 22 16:19 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 5773320 Sep 22 16:19 redis-server
[root@aliyun bin]# 

这里面就是redis内建的shell。

redis shell

  • redis-server redis的服务端,作用是启动redis服务
  • redis-cli 是redis的命令行客户端,用于连接redis服务操作redis
  • redis-benchmark 是redis的性能测试工具
  • redis-check-aof 是RedisAOF持久化文件检测和修复工具
  • redis-check-rdb 是redis RDB持久化文件的检测和修复工具
  • redis-sentinel 是redis哨兵功能模式,用于分布式

启动和关闭

启动使用redis-server命令,支持读配置文件和指定命令行参数的方式,一般包含的配置有:

  • 绑定的端口号
  • 日志文件
  • redis的工作目录
  • 是否以deamon的方式运行

启动服务

redis-server帮助文档:

[root@aliyun ~]# redis-server -h
Usage: ./redis-server [/path/to/redis.conf] [options] # 指定配置文件和option
       ./redis-server - (read config from stdin) 
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --slaveof 127.0.0.1 8888 # 作为127.0.0.1:8888实例的从实例
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

连接和使用服务

使用redis-cli这个内建的cli工具,或者使用官方提供的各种编程语言的api连接redis服务。

  • 使用redis cli连接
[root@aliyun ~]# redis-cli 
127.0.0.1:6379> set foo "hello redis"
OK
127.0.0.1:6379> get foo
"hello redis"
127.0.0.1:6379> exit

redis-cli有很多的参数,支持交互方式执行命令和非交互方式。

  • redis-cli帮助文档:
[root@aliyun ~]# redis-cli -h
redis-cli 4.0.10

Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
  -h <hostname>      Server hostname (default: 127.0.0.1). 也就是说可以连接远程的server
  -p <port>          Server port (default: 6379).  指定端口号连接,具体根据server的端口号
  -s <socket>        Server socket (overrides hostname and port).
  -a <password>      Password to use when connecting to the server.
  -u <uri>           Server URI.
  -r <repeat>        Execute specified command N times. 重复N次执行某个命令
  -i <interval>      When -r is used, waits <interval> seconds per command.
                     It is possible to specify sub-second times like -i 0.1.
  -n <db>            Database number.
  -x                 Read last argument from STDIN.
  -d <delimiter>     Multi-bulk delimiter in for raw formatting (default: \n).
  -c                 Enable cluster mode (follow -ASK and -MOVED redirections).
  --raw              Use raw formatting for replies (default when STDOUT is
                     not a tty).
  --no-raw           Force formatted output even when STDOUT is not a tty.
  --csv              Output in CSV format.
  --stat             Print rolling stats about server: mem, clients, ...
  --latency          Enter a special mode continuously sampling latency.
                     If you use this mode in an interactive session it runs
                     forever displaying real-time stats. Otherwise if --raw or
                     --csv is specified, or if you redirect the output to a non
                     TTY, it samples the latency for 1 second (you can use
                     -i to change the interval), then produces a single output
                     and exits.
  --latency-history  Like --latency but tracking latency changes over time.
                     Default time interval is 15 sec. Change it using -i.
  --latency-dist     Shows latency as a spectrum, requires xterm 256 colors.
                     Default time interval is 1 sec. Change it using -i.
  --lru-test <keys>  Simulate a cache workload with an 80-20 distribution.
  --slave            Simulate a slave showing commands received from the master.
  --rdb <filename>   Transfer an RDB dump from remote server to local file.
  --pipe             Transfer raw Redis protocol from stdin to server.
  --pipe-timeout <n> In --pipe mode, abort with error if after sending all data.
                     no reply is received within <n> seconds.
                     Default timeout: 30. Use 0 to wait forever.
  --bigkeys          Sample Redis keys looking for big keys.
  --hotkeys          Sample Redis keys looking for hot keys.
                     only works when maxmemory-policy is *lfu.
  --scan             List all keys using the SCAN command.
  --pattern <pat>    Useful with --scan to specify a SCAN pattern.
  --intrinsic-latency <sec> Run a test to measure intrinsic system latency.
                     The test will run for the specified amount of seconds.
  --eval <file>      Send an EVAL command using the Lua script at <file>.
  --ldb              Used with --eval enable the Redis Lua debugger.
  --ldb-sync-mode    Like --ldb but uses the synchronous Lua debugger, in
                     this mode the server is blocked and script changes are
                     are not rolled back from the server memory.
  --help             Output this help and exit.
  --version          Output version and exit.

Examples:
  cat /etc/passwd | redis-cli -x set mypasswd
  redis-cli get mypasswd
  redis-cli -r 100 lpush mylist x
  redis-cli -r 100 -i 1 info | grep used_memory_human:
  redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
  redis-cli --scan --pattern '*:12345*'

  (Note: when using --eval the comma separates KEYS[] from ARGV[] items)

When no command is given, redis-cli starts in interactive mode.
Type "help" in interactive mode for information on available commands
and settings.
  • 后台启动
[root@aliyun ~]# redis-server &

或者在配置文件中将daemonize设置为yes,然后启动时指定配置文件。

从使用方式可以看出redis整体上是一个C-S架构的组件,其实和mysql等DB看上去差不多,一个作为服务端的数据容器,客户端经由网络(实际上是基于TCP协议的RDBP)连接server,执行操作数据或者元数据的命令。

停止服务

  1. redis-cli shutdown
  2. 系统的kill命令(不要使用)

redis-cli shutdown命令是友好的停止命令,停止的过程包含三个阶段:

  • 断开与客户端的连接
  • 持久化数据 (可以指定save|nosave选项来选择是否进行持久化,默认会持久化)
  • 退出

使用kill命令会强制杀死进程,不会保存数据。

redis的K-V数据类型

key

key为string类型,是redis中的hashtable的key。

常用操作和命令

  • 判断key是否存在
exists foo
  • 设置可以值
set foo bar
  • 获取可以的value
get foo
  • 获取key的value的类型
type foo
  • 设置key的过期时间,单位是秒
expire foo seconds
  • 设置key的过期时刻,UNIX 时间戳,从UTC到时刻的秒数
expireat foo timestamp
  • 设置key的过期时间,单位毫秒
pexpire foo milliseconds
  • 取消key的过期设置,直接持久化,过期时间为-1,默认的都是持久的
persist key
  • 查看key的过期时间,单位秒
pttl key
  • 查看key的过期时间,单位毫秒
ttl key
  • 随机返回一个key
randomkey
  • 重命名一个key名
rename key newkey
  • 重命名key名为新的key名,要求新key不存在
renamenx key newkeynoexists
  • 返回匹配模式的key
keys pattern
  • 删除key
del foo
  • key的数量
dbsize
  • 测试
127.0.0.1:6379> set m 100
OK
127.0.0.1:6379> get m
"100"
127.0.0.1:6379> ttl m
(integer) -1
127.0.0.1:6379> expire m 3
(integer) 1
127.0.0.1:6379> ttl m
(integer) 1
127.0.0.1:6379> ttl m
(integer) -2
127.0.0.1:6379> get m
(nil)
127.0.0.1:6379> set m hello
OK
127.0.0.1:6379> del m
(integer) 1
127.0.0.1:6379> get m
(nil)
127.0.0.1:6379> 

value

value分多种数据类型包括:

  • string(基础)
  • hash(string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象)
  • list (字符串列表)
  • set(无序不重复的字符串集合)
  • Sorted set(有序集合)

可以通过命令type key来查看key对应的value的类型。

string

string是redis的基础数据类型,key的数据类型就是string,其他复合类型的数据也基于string。string最大能存储512MB的数据。

hash

即HashMap,和redis的基础结构类似,是一个key-value的数据类型。hash的key和value都是string类型(不支持嵌套的数据结构,如hash的value是hash这种事不存在的),hash的size为4字节空间,即32位有符号整形数的取值范围。

hash适合描述对象,类似于json的简化格式,因为不支持数据类型的嵌套,所有不能描述对象的属性还是对象这种模型。
只能支持类似:key field1 value1 field2 value2 ...

list

底层是双向链表实现的线性数据结构,所以在头尾追加节点的效率很高,但是随机访问效率就差了。容量空间也是32位。内部元素类型为string。可以在两端添加元素。

类似key e1 e2 e3

set

redis的Set是string类型的无序集合,元素不重复,重复添加的直接忽略。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
集合提供了求交集、并集、差集等操作。

sorted set

将Set中的元素增加一个权重参数score,元素按score有序排列。
由hash表和skiplist实现,所以即使读取中间位置的数据速度也很快(O(lgN))。

Skip List是一种随机化的数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间)。基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表(因此得名)。所有操作都以对数随机化的时间进行。Skip List可以很好解决有序链表查找特定值的困难。

参考资料

  • [1] Redis 教程
  • [2] 李子骅.Redis入门指南
  • [3] 付磊,张益军.Redis开发与运维
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容