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开发与运维
    原文作者:0x70e8
    原文地址: https://www.jianshu.com/p/6915d2f3c6c4
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞