redis入门(一)


redis入门(一)

目录

redis入门(一)
redis入门(二)
redis入门(三)linux

前言

  1. Redis是什么?
    redis是一种基于键值对(key-value)的NoSQL数据库。Redis会将全部数据都存放在内存中,因此它的读写性能很是惊人。不只如此,Redis还能够将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生相似断电或者机器故障的时候,内存中的数据不会“丢失”。Redis还提供了键过时、发布订阅、事务、流水线、Lua脚本等附加功能。git

  2. Redis能作什么
    在谈为何须要redis以前,先要清楚redis能够作什么。
  • 缓存。经过引入缓存加快数据的访问速度,下降后端数据源的压力。
  • 排行榜。redis提供给列表和有序几何数据结构能够很方便的构建各类排行榜系统。
  • 计数器。redis原生支持高性能的计数功能,能够为视频播放量、网页浏览数等提供支持。
  • 消息队列。redis提供发布订阅功能。

特性

咱们为何选择redis?github

速度快

官方给出的读写速度能够达到10W/s,如下是我本机双核四线程低压i7上测试的对字符串的读写速度。redis

C:\Users\Dm_ca> redis-benchmark -n 100000  -t set,get -q -a test1
SET: 11993.28 requests per second
GET: 57603.69 requests per second

若使用redis管道技术能够获得更高的读写速度shell

C:\Users\Dm_ca> redis-benchmark -n 100000 -t set,get -q -a test1 -P 2
SET: 19466.62 requests per second
GET: 133155.80 requests per second

Redis 管道技术能够在服务端未响应时,客户端能够继续向服务端发送请求,并最终一次性读取全部服务端的响应。数据库

下表是谷歌公司给出的各层级硬件执行速度,内存的响应速度是100ns,redis将数据所有从内存加载能够更快的读写数据。
20191024172138.pngubuntu

简单稳定

早期版本代码在2W行左右,3.0添加了集群等特性增值5W行。相比其余NoSQL数据库来讲代码量少得多。windows

丰富的功能

支持发布订阅、持久化、集群及管道等其余经常使用的功能。后端

历史

2008年,Redis的做者Salvatore Sanfilippo在开发一个叫LLOOGG的网站时,须要实现一个高性能的队列功能,最开始是使用MySQL来实现的,但后来发现不管怎么优化SQL语句都不能使网站的性能提升上去,因而他决定本身作一个专属于LLOOGG的数据库,这个就是Redis的前身。后来,Salvatore Sanfilippo将Redis1.0的源码开放到GitHub上,可能连他本身都没想到,Redis后来如此受欢迎。

历史版本

Redis借鉴了Linux操做系统对于版本号的命名规则:版本号第二位若是是奇数,则为非稳定版本(例如2.七、2.九、3.1),若是是偶数,则为稳定版本(例如2.六、2.八、3.0、3.2)。当前奇数版本就是下一个稳定版本的开发版本。

  1. Redis 2.6
    Redis 2.6在2012年正式发布,经历了17个版本,到 2.6.17版本,相比于Redis2.4,主要特性以下:
    • 服务端支持Lua脚本。
    • 从节点提供只读功能。
    • 重构了大量的核心代码,全部集群相关的代码都去掉了,cluster功能将会是3.0版本最大的亮点。
    • 其余若干修复与优化
  2. Redis 2.8
    Redis2.8在2013年11月22日正式发布,经历了24个版本,到2.8.24版本,相比于Redis2.6,主要特性以下:
    • 添加部分主从复制的功能,在必定程度上下降了因为网络问题,形成频繁全量复制生成RDB对系统形成的压力。
    • 能够经过config set命令设置maxclients。
    • 能够用bind命令绑定多个IP地址。
    • configre write命令能够将config set持久化到Redis配置文件中。
    • 其余若干修复与优化
  3. Redis 3.0
    • Redis Cluster:Redis的官方分布式实现。
    • 全新的embedded string对象编码结果,优化小对象内存访问,在特定的工做负载下速度大幅提高。
    • config set设置maxmemory时候能够设置不一样的单位单位(以前只能是字节)
    • incr命令性能提高。
    • 其余若干修复与优化
  4. Redis 3.2
    • 新的List编码类型:quicklist。
    • 从节点读取过时数据保证一致性。
    • 新的RDB格式,可是仍然兼容旧的RDB。
    • 加速RDB的加载速度。
    • 其余若干修复与优化
  5. Redis 4.0
    • 提供了模块系统,方便第三方开发者拓展Redis的功能
    • PSYNC2.0:优化了以前版本中,主从节点切换必然引发全量复制的问题。
    • 提供了RDB-AOF混合持久化格式,充分利用了AOF和RDB各自优点。
    • Redis Cluster兼容NAT和Docker。
    • 其余若干修复与优化

更多细节能够查看Redis版本历史介绍

安装与启动

redis编译后,有许多可执行文件,咱们先了解一下各个文件的用途。在windows版本和官方redis版的文件都是差很少的。

可执行文件 做用
redis-server 启动redis服务
redis-cli redis命令行客户端
redis-benchmark redis基准测试工具
redis-check-aof redis AOF持久化文件检测和修复工具
redis-check-dump redis RDB持久化文件检测和修复工具
redis-sentinel 启动redis哨兵服务

windows版本是没有redis-sentinel,在启动的时候能够经过--sentinel参数以哨兵模式启动。

安装

windows版本

  1. 下载

    Redis官方并不支持Windows操做系统,可是Redis做为一款优秀的开源技术吸引到了微软的注意,微软的开源技术组在GitHub上维护一个Redis的分支
    目前在windows版本最新的redis是3.2.100,能够到这里下载

    下载的压缩文件内容以下图所示。
    1.png

    windows版本的redis能够以2种方式运行,一种是经过cmd命令框启动redis服务进程。另外一种是将redis安装为windows服务,并以windows服务运行。

    .config是redis配置文件。在服务安装的时候咱们能够指定配置文件,若没有指定,则使用redis默认配置。

  2. 直接启动

    经过redis-server 配置名能够直接启动redis服务。
    20191029092007.png

  3. 安装服务

    生产环境建议将redis安装为windows服务,避免cmd框不当心被关掉。
    打开cmd窗口,经过redis-server --service-install 配置文件路径 --service-name 服务名安装服务。如redis-server --service-install redis.windows-service.conf --service-name redis-test
    若配置格式没有问题,安装成功后再windows服务中则会有名为redis-test的服务。

    安装windows服务时必须指定配置文件
    若没有指定服务名,则使用Redis做为默认的服务名称。

  4. 启动服务

    经过redis-server --service-start --service-name 服务名启动指定的redis服务。

  5. 中止服务

    经过redis-server --service-stop --service-name 服务名中止指定的redis服务。

  6. 卸载

    经过redis-server --service-install --service-name 服务名卸载Redis服务。卸载服务前须要先中止服务。

linux版本

  1. 下载

    在Linux安装软件一般有两种方法,第一种是经过各个操做系统的软件管理软件进行安装,例如CentOS有yum管理工具,Ubuntu有 apt。可是因为Redis的更新速度相对较快,而这些管理工具不必定能更新到最新的版本,同时Redis的安装自己不是很复杂,因此一推荐使用第二种方式:源码的方式进行安装,整个安装只需如下四步便可完成。
    1) 下载Redis指定版本的源码压缩包到当前目录。
    2) 解压缩Redis源码压缩包。
    3) 编译(编译以前确保操做系统已经安装gcc)。
    4) 安装。

    wget http://download.redis.io/releases/redis-5.0.5.tar.gz
    tar xzf redis-5.0.5.tar.gz
    cd redis-5.0.5
    make
  2. 编译

    我本机是在windows的Linux子系统上运行,安装的是Ubuntu,windows商店中的ubuntu是最小化安装,所以许多必要的开发包都是没有的,好比make,所以须要安装make,而编译redis源码还要依赖gcc,所以确保本身本地的linux已经安装了gccmake.

    在ubuntu下可使用sudo apt-get install build-essential安装gcc相关的包,使用sudo apt-get install make安装make包。
    若都安装完成,则能够在redis目录下经过make命令进行源码编译

  3. 启动

    经过src/redis-server启动redis-server,经过src/redis-server 配置名以指定的配置文件启动。若直接启动默认之前台服务进程执行,将会阻塞命令行。修改配置文件daemonize no改成daemonize yes以守护进程的方式执行。

    守护进程(Daemon Process),也就是一般说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,一般独立于控制终端而且周期性地执行某种任务或等待处理某些发生的事件。
    能够经过修改配置文件中的port修改绑定指定端口

  4. 客户端链接

    经过src/redis-cli链接redis服务,经过src/redis-server -vsrc/redis-cli -v能够查看redis的版本号。

数据类型与内部编码

数据结构

redis能够保存string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)。在后面的版本逐步又添加了Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等数据结构。

经过type命令能够查看当前键的数据类型。

127.0.0.1:26379> type key1
string

20191029103621.png

内部编码

经过type返回的仅仅是对外的数据结构,实际上每种数据结构都有本身底层的内部编码实现,并且是多种实现。

redis经过构建简单动态字符串、链表、压缩列表、整数集合、哈希表(字典)、跳跃表等内部编码构造出进行组合实现了各类数据结构,经过这种方式 ,Redis会在合适的场景选择合适的内部编码。从而优化不一样场景下的使用效率。

20191029103659.png

  • 若是一个字符串对象保存的是整数值,而且这个整数值能够用long类型来表示,须要注意的是long或double类型表示的浮点数在Redis中也是做为字符串值来保存的。若是咱们要保存一个浮点数到字符串对象里面,那么程序会先将这个浮点数转换成字符串值,而后再保存转换所得的字符串值。

  • embstr编码是专门用于保存短字符串的一种优化编码方式,embstr编码经过调用一次内存分配函数来分配一块连续的空间,而raw编码会调用两次内存分配函数。同理释放embstr编码的字符串只须要调用一次内存释放函数来分配一块连续的空间,而释放raw编码的字符串会调用两次内存释放函数。

    embstr编码的字符串对象其实是只读的。当咱们对embstr编码的字符串对象执行任何修改命令时,程序会先将对象的编码从embstr转换成raw,而后再执行修改命令。由于这个缘由,embstr编码的字符串对象在执行修改命令以后,总会变成一个raw编码的字符串对象。

  • Redis的字典使用哈希表做为底层实现,一个哈希表里面能够有多个哈希表节点,而每一个哈希表节点就保存了字典中的一个键值对。
  • 压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构。一个压缩列表能够包含任意多个节点(entry),每一个节点能够保存一个字节数组或者一个整数值。
  • 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,而且能够经过增删节点来灵活地调整链表的长度。
  • 整数集合(intset)是Redis用于保存整数值的集合抽象数据结构,它能够保存类型为int16_t、int32_t或者int64_t的整数值,而且保证集合中不会出现重复元素。
  • 跳跃表(skiplist)是一种有序数据结构,它经过在每一个节点中维持多个指向其余节点的指针,从而达到快速访问节点的目的。

经常使用API与使用场景

经常使用命令

  1. 查看全部键:keys *

    127.0.0.1:26379> set key1 1
    OK
    127.0.0.1:26379> set key2 2
    OK
    127.0.0.1:26379> set key3 3
    OK
    127.0.0.1:26379> set key22 22
    OK
    127.0.0.1:26379> keys *
    1) "key22"
    2) "key3"
    2) "key2"
    3) "key1"

    该命令还支持模糊查询
    shell 127.0.0.1:26379> keys *2* 1) "key22" 2) "key2"

  2. 键总数:dbsize

    127.0.0.1:26379> dbsize
    (integer) 3
  3. 检查键是否存在:exists key,能够传入多个key,返回存在key的个数

    127.0.0.1:26379> exists key1
    (integer) 1
    127.0.0.1:26379> exists key4
    (integer) 0
    127.0.0.1:26379> exists key1 key2
    (integer) 2
  4. 删除键:del key,能够同时删除多个key,返回成功删除key的数量

    127.0.0.1:26379> del key1 key2
    (integer) 2
  5. 键过时:expire key seconds

    127.0.0.1:26379> expire key3 2
    (integer) 1
  6. 查询键剩余过时时间:ttl key。大于等于0则是键剩余的过时时间,-1表示未设置过时时间。

    127.0.0.1:26379> ttl key3
    (integer) 2
    127.0.0.1:26379> ttl key1
    (integer) -1
  7. 查询redis服务状态:info [section]。能够经过info查询redis全部信息,或者经过info section查询指定的部分信息。

    127.0.0.1:26379> info
    # Server
    redis_version:5.0.6
    redis_git_sha1:00000000
    redis_git_dirty:0
    redis_build_id:6f31570182dc95d9
    redis_mode:standalone
    ...
    # Keyspace
    db0:keys=3,expires=0,avg_ttl=0
    
    127.0.0.1:26379> info keyspace
    # Keyspace
    db0:keys=3,expires=0,avg_ttl=

字符串

字符串类型是Redis最基础的数据结构。首先键都是字符串类型,并且其余几种数据结构都是在字符串类型基础上构建的,因此字符串类型能为其余四种数据结构的学习奠基基础。字符串类型的值实际能够是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),可是值最大不能超过512MB。

经常使用API

  1. 设置键set key value [ex seconds] [px milliseconds] [nx| xx]
    • ex seconds:为键设置秒级过时时间。
    • px milliseconds:为键设置毫秒级过时时间。
    • nx:键必须不存在,才能够设置成功,用于添加。
    • xx:与nx相反,键必须存在,才能够设置成功,用于更新。

    因为nx和xx的特性,只有一个客户端能设置成功,所以能够作为分布式锁的一种实现。

  2. 读取键:get key
  3. 批量设置:mset key value [key value ...]
  4. 批量读取:mget key [key ...]

内部编码

字符串类型的内部编码有3种:

使用场景

  1. 缓存

    20191031120713.png

    与关系型数据库不一样的是,Redis没有命令空间,并且也没有对键名有强制要求(除了不能使用一些特殊字符)。但设计合理的键名,有利于防止键冲突和项目的可维护性,比较推荐的方式是使用业务名:对象名:id:[属性]做为键名(也能够不是分号)。例如数据库名为vs,用户表名为user,那么对应的键能够用vs:user:1vs:user:1:name来表示,若是当前Redis只被一个业务使用,甚至能够去掉vs:。若是键名比较长,例如user:{uid}:friends:messages:{mid},能够在能描述键含义的前提下适当减小键的长度,例如变为u:{uid}:fr:m:{mid},从而减小因为键过长的内存浪费。

  2. 计数

    经过incr key对计数进行累加,可用于播放量,访问量等场景。

  3. 限速

    经过set 和 incr组合使用实现1分钟内最多发送5条短信。

    127.0.0.1:26379> set 182XXXXXXXX 1 ex 60 nx
    OK
    127.0.0.1:26379> set 182XXXXXXXX 1 ex 60 nx
    (nil)
    127.0.0.1:26379> incr 182XXXXXXXX
    (integer) 2

    能够看到经过nx参数只有在不存在的时候才会设置成功。

  4. 分布式锁

    能够经过set加nx或xx参数实现分布式锁。关于Redis实现分布式锁能够参考Distributed locks with Redis

列表

列表(list)类型是用来存储多个有序的字符串,一个列表最多能够存储2^32^-1个元素。在Redis中,能够对列表两端插入(push)和弹出(pop),还能够获取指定范围的元素列表、获取指定索引下标的元素等。列表是有序的,且能够插入重复数据。

经常使用API

  1. 从右边插入数据:rpush key value [value ...]
  2. 从左边插入数据:lpush key value [value ...]
  3. 从右边弹出数据:rpop key
  4. 从左边弹入数据:lpop key
  5. 从左侧阻塞弹出:blpop key [key ...] timeout
  6. 从右侧阻塞弹出:brpop key [key ...] timeout

    当使用阻塞弹出时,若列表为空,则将会阻塞指定的时间,若传递的timeout为0,会一致阻塞;若个客户端同时阻塞时,有数据插入列表时,先阻塞的先能够获取到值。

  7. 获取指定范围内的元素列表:lrange key start end
  8. 获取列表指定索引下标的元素:lindex key index
  9. 获取列表长度:llen key
  10. 修改指定索引下标的元素:lset key index newValue

内部编码

列表类型的内部编码有两种:

  • ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每一个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来做为列表的内部实现来减小内存的使用。
  • linkedlist(链表):当列表类型没法知足ziplist的条件时,Redis会使用linkedlist做为列表的内部实现。

    Redis3.2版本提供了quicklist内部编码,简单地说它是以一个ziplist为节点的linkedlist,它结合了ziplist和linkedlist二者的优点,为列表类型提供了一种更为优秀的内部编码实现

使用场景

  1. 消息队列
    Redis的lpush+brpop命令组合便可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
  • lpush+lpop=Stack(栈)
  • lpush+rpop=Queue(队列)
  • lpsh+ltrim=CappedCollection(有限集合)
  • lpush+brpop=MessageQueue(消息队列)

哈希

在Redis中,哈希类型是指键值自己又是一个键值对结构,形如value={{field1,value1},...{fieldN,valueN}}

经常使用API

  1. 设置值:hset key field value
  2. 获取指定键的field值:hget key field
  3. 删除指定键的field:hdel key field [field ...]
  4. 计算指定键的field的个数:hlen key
  5. 批量获取:hmget key field [field ...]
  6. 批量设置:hmset key field value [field value ...]
  7. 判断field是否存在:hexists key field
  8. 获取指定键的全部内容:hexists key field

内部编码

哈希类型的内部编码有两种:

  • ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时全部值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist做为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,因此在节省内存方面比hashtable更加优秀。
  • hashtable(哈希表):当哈希类型没法知足ziplist的条件时,Redis会使用hashtable做为哈希的内部实现,由于此时ziplist的读写效率会降低,而hashtable的读写时间复杂度为O(1)。

使用场景

  1. 缓存关系型数据库的用户信息

    • 关系型数据库保存方式
      20191029163219.png

    • hash类型保存方式
      20191029163253.png

    须要注意的是,关系型数据库是结构化的,每一列都要为其设置值(即便未空也可能包括NULL或特殊的标识表示NULL),而NOSQL则是稀疏的,有字段的才须要设置值。所以关系型数据库须要占用更大的内存空间。
    Redis不适合去模拟复杂的查询关系。

  2. 保存关系型数据的经常使用方式。
    • 每一个记录每条属性一个键。
      • 优势:简单直观,每一个属性均可以更新,互不影响。
      • 缺点:占用了太多的key。查找一个用户的信息比较麻烦,要获取n次key。
    • 将用户序列化后保存到一个键中。
      • 优势:合理的序列化提升redis内存使用效率。
      • 缺点:序列化和反序列化有必定的开销。同时每次更新一个属性都须要获取所有数据反序列化更新后再从新序列化保存到redis。
    • 每一个用户字段用对应一个field-value。
      • 优势:简单直观,合理使用能够减小redis内存使用。每一个属性互不影响。
      • 缺点:要控制hash的内部编码转换,若使用hashtable,会消耗更多内存。

集合

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不同的是,集合中不容许有重复元素,而且集合中的元素是无序的,不能经过索引下标获取元素。

经常使用API

  1. 添加元素:sadd key element [element ...]
  2. 删除元素:srem key element [element ...]

    添加和删除能够对多个元素进行操做,返回的是执行成功的数量。

  3. 计算元素个数:scard key
  4. 计算指定键的field的个数:hlen key
  5. 判断元素是否在集合中:sismember key element
  6. 还有一些集合的操做这里不作具体讲解

内部编码

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选用intset来做为集合的内部实现,从而减小内存的使用。
  • hashtable(哈希表):当集合类型没法知足intset的条件时,Redis会使用hashtable做为集合的内部实现。

使用场景

保存去重后的用户信息,好比IP白名单等

有序集合

有序集合它保留了集合不能有重复成员的特性,但不一样的是,有序集合中的元素能够排序。可是它和列表使用索引下标做为排序依据不一样的是,它给每一个元素设置一个分数(score)做为排序的依据。有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助咱们在实际开发中解决不少问题。

经常使用API

有序集合在集合基础上多了一个分值,并经过分支排序。

  1. 添加成员:zadd key score member [score member ...]。Redis3.2为zadd命令添加了nx、xx、ch、incr四个选项:
    • nx:member必须不存在,才能够设置成功,用于添加。
    • xx:member必须存在,才能够设置成功,用于更新。
    • ch:返回这次操做后,有序集合元素和分数发生变化的个数。
    • incr:对score作增长,至关于后面介绍的zincrby。
  2. 计算成员个数:zcard key
  3. 计算 某个 成员 的 分数 zscore key member
  4. 计算 成员 的 排名 zrank key member zrevrank key member
    • zrank是从分数从低到高返回排名。
    • zrevrank是从分数从高到低返回排名。
  5. 删除成员:zrem key member [member ...]
  6. 增长成员的分数:zincrby key increment member
  7. 返回指定排名范围的成员:zrange key start end [withscores]zrevrange key start end [withscores]
  8. 返回指定分数范围的成员:zrangebyscore key min max [withscores] [limit offset count]zrevrangebyscore key max min [withscores] [limit offset count]
  9. 返回指定分数范围成员个数:zcount key min max
  10. 删除指定排名内的升序元素:zremrangebyrank key start end
  11. 删除指定分数范围的成员:zremrangebyscore key min max

内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每一个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来做为有序集合的内部实现,ziplist能够有效减小内存的使用。
  • skiplist(跳跃表):当ziplist条件不知足时,有序集合会使用skiplist做为内部实现,由于此时ziplist的读写效率会降低。

使用场景

根据某个信息排序,好比一些排行榜功能,外卖的根据距离或综合评分排序等。

总结

本节简单介绍了redis历史。同时介绍了redis的安装部署的相关知识,最后介绍了开发经常使用的一些API和使用场景。


参考文档

  1. redis
  2. redis开发与运维
  3. Redis版本历史介绍
  4. redis配置文件详解
  5. linux下/var/run目录下.pid文件的做用
  6. Redis的embstr与raw编码方式再也不以39字节为界了
  7. Distributed locks with Redis

本文地址:http://www.javashuo.com/article/p-oicoxmss-kw.html 做者博客:杰哥很忙 欢迎转载,请在明显位置给出出处及连接

相关文章
相关标签/搜索