Redis基础知识
Posted happy-king
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis基础知识相关的知识,希望对你有一定的参考价值。
一、Redis基础知识
一、知识链接
redis中文网站:http://www.redis.net.cn/ 和 http://redis.cn/
redis官网:http://redis.io/
命令的链接:http://redisdoc.com/
二、缓存
1、查看缓存:最后修改时间
访问以下网站时,当你只是刷新时,谷歌按F12你会发现,并最后修改时间,并没有发生改变:因为你访问是缓存
# curl --head www.baidu.com HTTP/1.1 200 OK Server: bfe/1.0.8.18 Date: Fri, 16 Dec 2016 03:18:29 GMT Content-Type: text/html Content-Length: 277 Last-Modified: Mon, 13 Jun 2016 02:50:07 GMT 最后修改时间 Connection: Keep-Alive ETag: "575e1f5f-115" Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform Pragma: no-cache Accept-Ranges: bytes
2、缓存体系
转自 【转载请注明来自于-运维社区】https://www.unixhot.com/page/cache
Web架构知识体系之缓存 | |||
缓存分层 | 缓存分级 | 内容 | 内容简介 |
用户层 | DNS | DNS系统本地缓存 | 客户端操作系统DNS缓存 |
LocalDNS缓存 | 本地DNS提供商的缓存 | ||
DNS缓存服务器 | 专用的DNS缓存服务器 | ||
浏览器DNS缓存 | Firefox默认60秒,HTML5的新特性:DNS Prefetching | ||
应用程序DNS缓存 | Java(JVM)、php语言本身的DNS缓存 | ||
浏览器 | 浏览器缓存 | HMTL5新特性:Link Prefetching | |
基于最后修改时间的HTTP缓存协商: Last-Modified | |||
基于过期时间的HTTP缓存协商: Expires、cache-control | |||
基于打标签的HTTP缓存协商: Etag | |||
代理层 | CDN | 反向代理缓存 | 基于Squid、Varnish、nginx、ATS等,一般有多级 |
Web层 | 解释器 | Opcache | 操作码缓存 |
Web服务器 | Web服务器缓存 | Apache(mod_cache)、Nginx(FastCGI缓存、Proxy cache) | |
应用层 | 应用服务 | 动态内容缓存 | 缓存动态内存输出 |
Local Cache | 应用本地缓存,PHP(Yac、Xcache) Java(ehcache) | ||
页面静态化 | 动态页面静态化,专门用于静态化的CMS | ||
数据层 | 分布式缓存 | 分布式缓存 | Memcache、Redis |
数据库 | mysql | innodb缓存、MYISAM缓存 | |
系统层 | 操作系统 | CPU Cache | L1(数据缓存、指令缓存) L2、L3 |
内存Cache | 内存高速缓存、Page Cache | ||
物理层 | 磁盘 | Disk Cache | 磁盘缓存(Cache memory) |
硬件 | Raid Cache | 磁盘阵列缓存 | |
备注 | 1.此体系结构仅包含缓存(Cache),不包含缓冲(Buffer),所有很多缓冲区没有列举。 2.根据用户发起一个HTTP请求开始,持续更新中,欢迎大家添加更多的内容。 |
3、为什么静态资源(图片)配置单独的域名,这样做有什么好处?
1、可以做组件分离(为不同的资源,配备不同的存储和Web访问,比如动静分离)
例如:大小图片的处理机制是不一样的,配置不同的调配参数
block的大小,默认是4K(原因:因为内存的一个页也是4K)
2、静态的资源方便上CDN
动态没必要上CDN,因为它的变化频率大;静态的需要上CDN,提升用户的体验,这样的话方便上CDN
3、加快页面打开速度,提高浏览器并发
浏览器请求并发数是基于域名的
不同的版本的不同浏览器的并发不一样
4、配置不同的域名:www.jd.com pic.jd.com www.jdpic.com
后两个域名的区别特别大
- 动态请求写入的cookie,浏览器每次请求本域名下的其他资源,都会附带cookie
- 若你使用pic.jd.com访问的时候,访问图片也是需要附带cookie的
- 若你想把静态资源单独存放,注意一定要使用另外一个顶级域名www.jdpic.com,这样不会产生cookie了
1)提升了访问的速度,从而提生了用户的体验
2)减少了带宽,为企业节省了成本
域名多的情况下,弊端就是DNS解析的时间多了,但是这个时间是可以忽略不计的
4、分布式缓存Redis
1、redis缓存
redis不单单可以做缓存;写的时候,就把它当成数据库写的
redis是VM vare支持的
2、安装redis的方式
- 源码安装
- 编译安装
- 但是在生产环境中yum安装是最佳实践方式,但是可以兼容两者的优点,为企业定制的yum仓库
三、Redis概况
1、Redis简介
- Redis是一个开源的使用ANSI C语言编写的Key-Value 内存数据库
- 读写性能强,支持多种数据类型
- 把数据存储在内存中的高速缓存
- 作者Salvatore Sanfilippo
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。
Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
2、Redis特点
- 速度快
- 支持多种数据结构(string、list、hash、set、storted set)
- 持久化
- 主从复制(集群)
- 支持过期时间
- 支持事务:举例:转账
- 消息订阅
- 官方不支持WINDOWS,但是有第三方版本
- 支持事务:
- 消息订阅:举例:微博 最大的用户是新浪微博
3、Redis和memcache对比
|
4、Redis性能测试
redis本身是单线程程序 (线程层面)
5、redis的应用场景
1、数据缓存
提高访问性能,使用的方式与memcache相同。 主要是电商企业
2、会话缓存(Session Cache)
保存web会话信息 超过5000个会话,NFS是个瓶颈
3、排行榜/计数器
Nginx+lua+Redis计数器进行IP自动封禁。
4、消息队列:新浪微博
构建实时消息系统,聊天,群聊。
三、 如何设计一个电商的购物车
1、需求
用户把产品放入购物车,用户下次访问的时候,购物车结算的商品还在。(把用户的购物车记录下来)
2、记录放在哪里
用户不登录:购物车的内容放在cookie
用户登录后:购物车的内容存放在redis uid_xxx value购物车,设置过期时间
数据库读缓存
3、负载均衡
session处理有几种方式
- 会话保持:ip_hash(例:nginx)cookie(浏览器)
- 会话复制:tomcat cluster(多个节点之间使用会话复制)
- 会话共享:放在redis里
1)语言支持多
2) 简单、高效
3)所有开发都会 PHP的配置文件php.ini配置session存储位置;tomcat sessionmanager
二、Redis持久化
一、Redis的数据存储
1、图解Redis持久化方式
2、文解Redis持久化
- rdb 实际的数据
- aof 一条条操作记录下来
第二条 但设置完后,当超过数量,会直接剔除最旧的数据
3、Redis持久化两种方式的应用
- RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
- AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
- Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
- 你甚至可以关闭持久化功能,让数据只在服务器运行时存在
二、RDB持久化方式
1、RDB的优缺点
1、RDB的优点
- RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
- RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。
- RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
- RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
2、RDB的缺点
- 如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。
- 每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。
2、持久化策略
1、日志文件
appendonly yes/no
2、修改redis的配置文件redis.conf
86 save 900 1 ##每900s内有1个键发生变化,做一个快照 87 save 300 10 ##每300s内有10个键变化,就做一个快照 88 save 60 10000 ##60s内有10000个键变化,就做一个快照
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改,即将数据写入硬盘。
这个需要优化,一般情况下是关闭的 (当没有MySQL的情况下,必须开启)
3、redis的工作目录(可以自己定义)
106 # Note that you must specify a directory here, not a file name. 107 dir /var/lib/redis/
4、查看redis的RDB备份的文件
[[email protected] redis]# ll total 4 -rw-r--r-- 1 redis redis 243 Dec 26 10:19 dump.rdb [[email protected] redis]# file dump.rdb dump.rdb: data ##当你快照完成后,可以将原来的rdb文件替换掉
4、压缩
dbcompression yes
指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
节省空间,浪费CPU(根据企业的现况,具体考量,决策)
5、同步
appendfsync everysec
- no:表示等操作系统进行数据缓存同步到磁盘(快)
- always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
- everysec:表示每秒同步一次(折衷,默认值)
1、RDB快照
在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。
你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。
你也可以通过调用 SAVE 或者 BGSAVE , 手动让 Redis 进行数据集保存操作。
比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动保存一次数据集:
save 60 1000
这种持久化方式被称为快照(snapshot)。
2、快照的运行方式
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
- Redis 调用 fork() ,同时拥有父进程和子进程。
- 子进程将数据集写入到一个临时 RDB 文件中。
- 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。
三、AOF持久化方式
1、AOF的优缺点
1、AOF的优点
- 使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。
- AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。
- Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
- AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
2、AOF的缺点
- 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
- AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。
3、只进行追加操作的文件(append-only file,AOF)
快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。
尽管对于某些程序来说, 数据的耐久性并不是最重要的考虑因素, 但是对于那些追求完全耐久能力(full durability)的程序来说, 快照功能就不太适用了。
从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。
你可以通过修改配置文件来打开 AOF 功能:
appendonly yes
从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。
这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
4、配置
修改配置文件redis.conf
266 # log file in background when it gets too big. 267 268 appendonly yes ###将no改成yes
5、AOF的运行方式
AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制。
以下是 AOF 重写的执行步骤:
- Redis 执行 fork() ,现在同时拥有父进程和子进程。
- 子进程开始将新 AOF 文件的内容写入到临时文件。
- 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾: 这样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
- 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
搞定!现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾
三、RDB 和 AOF选择
1、 RDB 和 AOF ,我应该用哪一个?
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
因为以上提到的种种原因, 未来我们可能会将 AOF 和 RDB 整合成单个持久化模型。 (这是一个长期计划。)
接下来的几个小节将介绍 RDB 和 AOF 的更多细节。
注意:
- 生产中使用for循环时一定要非常小心
- 先在命令行一步步测试然后再执行比较繁琐的命令
[[email protected] redis]# for ((i=1;i<=1000;i++));do echo $i;done [[email protected] redis]# for ((i=1;i<=1000;i++));do redis-cli -h 10.0.0.150 set k$i $i;done
2、 怎么从 RDB 持久化切换到 AOF 持久化
在 Redis 2.2 或以上版本,可以在不重启的情况下,从 RDB 切换到 AOF :
1)为最新的 dump.rdb 文件创建一个备份。
2)将备份放到一个安全的地方。
3)执行以下两条命令: ###配置文件也要弄
redis-cli> CONFIG SET appendonly yes redis-cli> CONFIG SET save ""
4)确保命令执行之后,数据库的键的数量没有改变。
5)确保写命令会被正确地追加到 AOF 文件的末尾。
步骤 3 执行的第一条命令开启了 AOF 功能: Redis 会阻塞直到初始 AOF 文件创建完成为止, 之后 Redis 会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾。
步骤 3 执行的第二条命令用于关闭 RDB 功能。 这一步是可选的, 如果你愿意的话, 也可以同时使用 RDB 和 AOF 这两种持久化功能。
别忘了在 redis.conf 中打开 AOF 功能! 否则的话, 服务器重启之后, 之前通过 CONFIG SET 设置的配置就会被遗忘, 程序会按原来的配置来启动服务器。
四、Redis备份
1、备份Redis数据
阅读这个小节前, 先将下面这句话铭记于心: 一定要备份你的数据库!
需求:磁盘故障, 节点失效, 诸如此类的问题都可能让你的数据消失不见, 不进行备份是非常危险的。
Redis 对于数据备份是非常友好的, 因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的 RDB 文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用 rename(2) 原子地用临时文件替换原来的 RDB 文件。
这也就是说, 无论何时, 复制 RDB 文件都是绝对安全的。
1、建议如下
- 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
- 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
- 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
2、容灾备份
Redis 的容灾备份基本上就是对数据进行备份, 并将这些备份传送到多个不同的外部数据中心。
容灾备份可以在 Redis 运行并产生快照的主数据中心发生严重的问题时, 仍然让数据处于安全状态。
因为很多 Redis 用户都是创业者, 他们没有大把大把的钱可以浪费, 所以下面介绍的都是一些实用又便宜的容灾备份方法:
- Amazon S3 ,以及其他类似 S3 的服务,是一个构建灾难备份系统的好地方。 最简单的方法就是将你的每小时或者每日 RDB 备份加密并传送到 S3 。 对数据的加密可以通过 gpg -c 命令来完成(对称加密模式)。 记得把你的密码放到几个不同的、安全的地方去(比如你可以把密码复制给你组织里最重要的人物)。 同时使用多个储存服务来保存数据文件,可以提升数据的安全性。
- 传送快照可以使用 SCP 来完成(SSH 的组件)。 以下是简单并且安全的传送方法: 买一个离你的数据中心非常远的 VPS , 装上 SSH , 创建一个无口令的 SSH 客户端 key , 并将这个 key 添加到 VPS 的 authorized_keys 文件中, 这样就可以向这个 VPS 传送快照备份文件了。 为了达到最好的数据安全性,至少要从两个不同的提供商那里各购买一个 VPS 来进行数据容灾备份。
需要注意的是, 这类容灾系统如果没有小心地进行处理的话, 是很容易失效的。
最低限度下, 你应该在文件传送完毕之后, 检查所传送备份文件的体积和原始快照文件的体积是否相同。 如果你使用的是 VPS , 那么还可以通过比对文件的 SHA1 校验和来确认文件是否传送完整。
另外, 你还需要一个独立的警报系统, 让它在负责传送备份文件的传送器(transfer)失灵时通知你
三、Redis支持的数据类型
一、常规的操作
1、操作key前需要检查
- KEYS * 查看KEY支持通配符 (生产环境慎用)
- DEL删除给定的一个或多个key
- EXISTS 检查是否存在
- EXPIRE 设定生存时间
- TTL以秒为单位返回过期时间
- DUMP RESTORE序例化与反序列化
- PEXIRE PTTL PERSIST 以毫秒为单位
- RENAME 变更KEY名
- SORT 键值排序
- TYPE返回键所存储值的类型
127.0.0.1:6379> expire foo 20 (integer) 1 127.0.0.1:6379> get foo "wzs" 127.0.0.1:6379> TTL foo (integer) 7 127.0.0.1:6379> get foo (nil)
二、字符串
1、知识点
SET name "guohz“ Get name
一个键默认最大能存储512MB
- Append将 value 追加到 key 原来的值的末尾
- Mget mset同时设置一个或多个键值对
- STRLEN 返回字符串长度
- INCR DECR 将值增或减1
- INCRBY DECRBY 减去指定量
- DECRBY count 20
2、命令实践
127.0.0.1:6379> keys * 1) "foo" 127.0.0.1:6379> set name wzs OK 127.0.0.1:6379> append name yjj (integer) 6 127.0.0.1:6379> get name "wzsyjj" 127.0.0.1:6379> mset key k1 key2 k2 key3 k3 OK 127.0.0.1:6379> mget key key2 key3 1) "k1" 2) "k2" 3) "k3"
127.0.0.1:6379> incr num (integer) 2001 127.0.0.1:6379> decr num (integer) 2000 127.0.0.1:6379> decr num (integer) 1999
127.0.0.1:6379> incrby num 100 (integer) 2099 127.0.0.1:6379> decrby num 100 (integer) 1999
三、hash(哈希)
1、知识点
Redis hash 是一个键值对集合。 Redis hash是一个string类型的field和value的映射表 hash特别适合用于存储对象。 每个 hash 可以存储 2^32 -1(4294967295) 键值对
2、常用命令
- HSET HGET 设置返回单个值
- HMSET HMGET 设置返回多个值
- Hmset user name guo sex male age 22
- HGETALL 返回KEY的所有键值
- HEXSITS HLEN
- HKEYS HVALS 获取所有字段或值
- HDEL 删除key 中的一个或多个指定域
3、命令实战
127.0.0.1:6379> hset h1 name wzs (integer) 1 127.0.0.1:6379> hget h1 name "wzs" 127.0.0.1:6379> hset h1 sex male (integer) 1 127.0.0.1:6379> hset h1 age 28 (integer) 1 127.0.0.1:6379> hget h1 name "wzs"
127.0.0.1:6379> hgetall h1 1) "name" 2) "wzs" 3) "sex" 4) "male" 5) "age" 6) "28"
127.0.0.1:6379> hkeys h1 1) "name" 2) "sex" 3) "age" 127.0.0.1:6379> hvals h1 1) "wzs" 2) "male" 3) "28"
四、list(列表)
1、知识点
Redis列表是简单的字符串列表。 按照插入顺序排序每个 LIST可以存储 2^32 -1 键值对
2、常用命令
- LPUSH 将一个或多个值插入到列表头部
- RPUSH将一个或多个值插入到列表尾部
- LPOP/RPOP 移除表头/尾的元素
- LLEN 返回列表长度
- LRANGE 返回指定的元素
- LREM greet 2 morning 删除前两个morning
- LREM greet -1 morning 删除后一个morning
- LREM greet 0 hello 删除所有hello
- Lindex 返回列表 key 中下标为 index 的元素.
- LSET key index value
- 将列表 key 下标为 index 的元素的值设置为 value
- LINSERT 插入数据位于某元素之前或之后。
- LINSERT key BEFORE|AFTER pivot value
3、命令实战
127.0.0.1:6379> lpush list1 guo hong ze old boy (integer) 5 127.0.0.1:6379> lrange list1 0 10 1) "boy" 2) "old" 3) "ze" 4) "hong" 5) "guo" 127.0.0.1:6379> lrange list1 0 10 1) "wzs" 127.0.0.1:6379> rpush list1 yjj 127.0.0.1:6379> lpop list1 "wzs" 127.0.0.1:6379> rpop list1 "yjj" 127.0.0.1:6379> llen list1 (integer) 5 127.0.0.1:6379> lrem list1 2 morning (integer) 2 127.0.0.1:6379> lrange list1 0 10 1) "pn" 2) "addd" 3) "morning" 4) "boy" 5) "old" 6) "ze" 7) "hong" 8) "guo" 127.0.0.1:6379> lset list1 2 lidazhao
五、集合(set)
1、知识点
- Redis的Set是string类型的无序集合。
- 集合成员是唯一的,这就意味着集合中不能出现重复的数据。
- Redis 中集合是通过哈希表实现的。
2、常用命令
- SADD key member [member ...]:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
- SCARD key 返回集合KEY的基数
- SDIFF key1 key2:返回一个集合的全部成员,该集合是所有给定集合之间的差集,注意前后顺序。比较后Sdiffstore进行存储
- SMEMBERS key 查看成员的值
- SUNION 返回一个集合的全部成员,该集合是所有给定集合的并集。SUNIONSTORE
- SINTER key [key ...]:返回一个集合的全部成员,该集合是所有给定集合的交集。SINTERSTORE
- SISMEMBER 判断是否属于该集合
- SMOVE source destination member:将 member 元素从 source 集合移动到 destination 集合。
- SPOP SRANDMEMBER 移出或读取一个随机元素。
- SREM 移除集合中一个或多个元素
3、命令实战
比较有前后顺序
127.0.0.1:6379> sadd set1 wzs yjj zy (integer) 3 127.0.0.1:6379> sadd set1 wzs zhangsanfeng (integer) 1 127.0.0.1:6379> scard set1 (integer) 4 127.0.0.1:6379> sadd set2 wzs zhangsanfeng oldboy sjh laosiji (integer) 5 127.0.0.1:6379> sdiff set1 set2 1) "yjj" 2) "zy" 127.0.0.1:6379> sdiff set2 set1 1) "sjh" 2) "oldboy" 3) "laosiji" 127.0.0.1:6379> SMEMBERS set2
六、有序集合
1、知识点
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
2、常用命令
- ZADD key score member
- ZCARD 返回有序集 key 的基数
- ZCOUNT key min max
- ZCOUNT salary 2000 5000 计算2000到5000之间的数
- ZSCORE key member 返回值
- ZINCRBY key increment member:为score 值加上增量 increment,负数为减法
- ZINCRBY salary 2000 tom
- ZRANGE key start stop 返回指定区间成员
- ZRANGE salary 0 -1 WITHSCORES 显示所有
- ZRANGEBYSCORE:有序集成员按 score 值递增(从小到大)次序排列。
- ZRANGEBYSCORE salary -inf +inf WITHSCORES
- ZRANK key member 显示排名
- ZRANGE salary 0 -1 WITHSCORES
- ZRANGE salary tom
- ZREM key member 移除一个或多个成员。
- ZREMRANGEBYRANK ZREMRANGEBYSCORE 移除
- ZREVRANGE key start stop [WITHSCORES]:递减返回值
3、常用命令
ZRANGEBYSCORE salary -inf +inf WITHSCORES
127.0.0.1:6379> zadd salary 10000 wzs (integer) 1 127.0.0.1:6379> zscore salary wzs "10000" 127.0.0.1:6379> zadd salary 13000 oldboy (integer) 1 127.0.0.1:6379> zadd salary 9000 zy (integer) 1 127.0.0.1:6379> zadd salary 12000 yjj (integer) 1 127.0.0.1:6379> zcount salary 10000 20000 (integer) 3
127.0.0.1:6379> zincrby salary 1000 wzs "11000" 127.0.0.1:6379> zscore salary wzs "11000"
127.0.0.1:6379> zincrby salary -1000 zy "8000" 127.0.0.1:6379> zscore salary zy "8000"
127.0.0.1:6379> zrange salary 0 -1 1) "zy" 2) "wzs" 3) "yjj" 4) "oldboy" 127.0.0.1:6379> zrange salary 0 -1 withscores 开始到最后 1) "zy" 2) "8000" 3) "wzs" 4) "11000" 5) "yjj" 6) "12000" 7) "oldboy" 8) "13000" 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf WITHSCORES 127.0.0.1:6379> ZRANGEBYSCORE salary 10000 20000 WITHSCORES 1) "wzs" 2) "11000" 3) "yjj" 4) "12000" 5) "oldboy" 6) "13000" 127.0.0.1:6379> ZRANGEBYSCORE salary 10000 20000 1) "wzs" 2) "yjj" 3) "oldboy"
四、Redis的高级应用
一、发布订阅
1、生产消费模型
2、消息模式
发布消息通常有两种模式:队列模式(queuing)和发布-订阅模式(publish-subscribe)。
队列模式中,consumers可以同时从服务端读取消息,每个消息只被其中一个consumer读到。
发布-订阅模式中消息被广播到所有的consumer中,topic中的消息将被分发到组中的一个成员中。同一组中的consumer可以在不同的程序中,也可以在不同的机器上。
3、Redis的发布订阅
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
1、发布订阅实例
SUBSCRIBE mq1 #客户端
PUBLISH mq1 "Redis is a great caching technique"
- PSUBSCRIBE订阅一个或多个符合给定模式的频道。
- psubscribe news.* tech.*
- PUBLISH channel message
- 将信息 message 发送到指定的频道 channel 。返回值代表消费者数量
- pubsub channels 显示订阅频道
- PUBSUB NUMSUB news.it 打印各频道订阅者数量
- PUNSUBSCRIBE 退订多个频道
- SUBSCRIBE 订阅给定的一个或多个频道的信息。
- UNSUBSCRIBE 退订频道
127.0.0.1:6379> subscribe channel1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "channel1" 3) (integer) 1 1) "message" 2) "channel1"
127.0.0.1:6379> pubsub channels 1) "channel1" 127.0.0.1:6379> pubsub numsub channel1 1) "channel1" 2) (integer) 2
二、Redis事务
1、知识点
1、Redis 事务可以一次执行多个命令。
事务的特性:原子性、一致性、分离性、持久性
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 原子性:事务中的命令要么全部被执行,要么全部都不执行。
2、执行过程
- 开始事务。
- 命令入队。
- 执行事务。
2、事务命令
- DISCARD :取消事务,放弃执行事务块内的所有命令。
- EXEC :执行所有事务块内的命令。
- MULTI :标记一个事务块的开始。
- UNWATCH :取消 WATCH 命令对所有 key 的监视。
- WATCH key [key ...] :监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
3、实战:事务执行
zadd salary 2000 guohongze zadd salary 3000 oldboy ZRANGE salary 0 -1 WITHSCORES MULTI ZINCRBY salary 1000 guohongze zincrby salary -1000 oldboy EXEC 127.0.0.1:6379> multi OK 127.0.0.1:6379> zincrby salary -1000 yjj QUEUED 127.0.0.1:6379> zincrby salary 1000 wzs QUEUED 127.0.0.1:6379> exec 1) "11000" 2) "12000"
三、Redis服务的命令
Info Client list Client kill ip:port config get * CONFIG RESETSTAT 重置统计 CONFIG GET/SET 动态修改 Dbsize FLUSHALL 清空所有数据 select 1 FLUSHDB 清空当前库 MONITOR 监控实时指令 SHUTDOWN 关闭服务器 save将当前数据保存 SLAVEOF host port 主从配置 SLAVEOF NO ONE SYNC 主从同步 ROLE返回主从角色
四、慢日志查询
1、命令详解
Slow log 是 Redis 用来记录查询执行时间的日志系统。 slow log 保存在内存里面,读写速度非常快 可以通过改写 redis.conf 文件或者用 CONFIG GET 和 CONFIG SET 命令对它们动态地进行修改 slowlog-log-slower-than 10000 超过多少微秒 CONFIG SET slowlog-log-slower-than 100 CONFIG SET slowlog-max-len 1000 保存多少条慢日志 CONFIG GET slow* SLOWLOG GET SLOWLOG RESET
2、命令
127.0.0.1:6379> config set slowlog-max-len 256 OK 127.0.0.1:6379> config get slow* 1) "slowlog-log-slower-than" 2) "10000" 3) "slowlog-max-len" 4) "256"
五、数据备份
- CONFIG GET dir 获取当前目录
- Save 备份(无持久化策略时),生成时在redis当前目录中。
- 恢复时只需将dump.rdb放入redis当前目录
1、备份数据
127.0.0.1:6379> CONFIG GET dir 1) "dir" 2) "/data/server/redis/src" 127.0.0.1:6379> config set dir /data/server/redis OK 127.0.0.1:6379> CONFIG GET dir 1) "dir" 2) "/data/server/redis" 127.0.0.1:6379> save OK
[[email protected] redis]# ls 00-RELEASENOTES deps MANIFESTO runtest src BUGS dump.rdb
2、恢复数据
五、Redis的主从复制(读写分离)/哨兵(主从切换)配置
一、Redis主从复制知识点
- 从 Redis 2.8 开始,使用异步复制。
- 一个主服务器可以有多个从服务器。
- 从服务器也可以有自己的从服务器。
- 复制功能不会阻塞主服务器。
- 可以通过复制功能来让主服务器免于执行持久化操作,由从服务器去执行持久化操作即可
当数据量变得庞大的时候,读写分离还是很有必要的。同时避免一个redis服务宕机,导致应用宕机的情况,我们启用sentinel(哨兵)服务,实现主从切换 的功能。redis提供了一个master,多个slave的服务。
准备三个redis服务,依次命名文件夹子master,slave1,slave2.这里为在测试机上,不干扰原来的redis服务,我们master使用6000端口。
二、修改Redis主从的配置
注意:配置文件的位置,根据实际情况更改
1、配置详解
slaveof 192.168.1.1 6379 slave-read-only 只读模式 masterauth <password> 主服务器设置密码后需要填写密码 min-slaves-to-write <number of slaves> 从服务器不少于,才允许写入 min-slaves-max-lag <number of seconds> 从服务器延迟不大于 CONFIG set slave-read-only yes Config set masterauth root INFO replication SLAVEOF NO ONE 升级至MASTER
2、master修改配置
port 6000 requirepass 123456
3、slave1修改配置
port 6001 slaveof 127.0.0.1 6000 masterauth 123456 requirepass 123456
4、slave2修改配置
port 6002 slaveof 127.0.0.1 6000 masterauth 123456 requirepass 123456
requirepass:是认证密码,应该之后要作主从切换,所以建议所有的密码都一致。masterauth是从机对主机验证时,所需的密码(即主机的requirepass)。
三、启动主机
注意:配置文件的位置,根据实际情况更改
1、启动master
redis-server redis.conf
2、启动slave
redis-server redis1.conf
redis-server redis2.conf
3、查看启动后进程和端口
ps -ef |grep redis ss -lutnp
四、验证主从复制
1、master
# redis-cli -h 127.0.0.1 -p 6000 127.0.0.1:6000> auth 123456 OK 127.0.0.1:6000> set test chenqm OK
2、slave1
# redis-cli -h 127.0.0.1 -p 6001 127.0.0.1:6001> auth 123456 OK 127.0.0.1:6001> get test "chenqm"
3、slave2
# redis-cli -h 127.0.0.1 -p 6002 127.0.0.1:6001> auth 123456 OK 127.0.0.1:6001> get test "chenqm"
可以看到主机执行写命令,从机能同步主机的值,主从复制,读写分离就实现了。
五、Redis哨兵(sentinel)实现主从切换
万一主机挂了怎么办,这是个麻烦事情,所以redis提供了一个sentinel(哨兵),以此来实现主从切换的功能,类似与zookeeper。
注意:配置文件的位置,根据实际情况更改
启动三个哨兵
哨兵sentinel官网链接:https://redis.io/topics/sentinel
1、Sentinel的基本知识
- 您需要至少三个Sentinel实例才能实现可靠的部署。
- 三个Sentinel实例应放置在相信独立失败的计算机或虚拟机中。例如,不同的物理服务器或虚拟机在不同的可用区域上执行。
- 由于Redis使用异步复制,Sentinel + Redis分布式系统不能保证在故障期间保留已确认的写入。然而,有些方法可以部署Sentinel,使窗口可以丢失局限于某些时刻的写入,而另外还有其他安全性较低的部署方式。
- 您的客户需要支持Sentinel。受欢迎的客户端库支持Sentinel,但不是全部。
- 如果您不在开发环境中进行不定期测试,或者在生产环境中可以更好地进行测试(如果可行),那么就没有安全的HA设置。你可能有一个错误的配置,只有当它太迟了(凌晨3点,当你的主站停止工作时)才会显现出来。
- Sentinel,Docker或其他形式的网络地址转换或端口映射应该小心:Docker执行端口重新映射,打破其他Sentinel进程的Sentinel自动发现以及主服务器的从属列表。有关更多信息,请查看本文后面有关Sentinel和Docker的部分。
2、配置 三个sentinel进程
master的sentinel.conf
port 26279 entinel monitor mymaster 127.0.0.1 6000 2 sentinel auth-pass mymaster 123456
slave1的sentinel.conf
port 26379 entinel monitor mymaster 127.0.0.1 6000 2 sentinel auth-pass mymaster 123456
slave2的sentinel.conf
port 26479 sentinel monitor mymaster 127.0.0.1 6000 2 sentinel auth-pass mymaster 123456
3、启动sentinel服务(到对应的目录执行相应的命令)
启动方式一:
如果您使用的是redis-sentinel
可执行文件(或者如果您的可执行文件具有该名称的符号链接redis-server
),则可以使用以下命令行运行Sentinel:
redis-sentinel /path/to/sentinel.conf
启动方式二:
redis-server sentinel.conf --sentinel
查看日志
[7014] 11 Jan 19:42:30.918 # +monitor master mymaster 127.0.0.1 6000 quorum 2 [7014] 11 Jan 19:42:30.923 * +slave slave 127.0.0.1:6002 127.0.0.1 6002 @ mymaster 127.0.0.1 6000 [7014] 11 Jan 19:42:30.925 * +slave slave 127.0.0.1:6001 127.0.0.1 6002 @ mymaster 127.0.0.1 6000
从对应的日志观察到,一个master服务,两个slave服务。
4、验证
1、 直接验证:哨兵
新开一个命令行窗口进入redis的src目录,用redis-cli工具登录其中一个哨兵
redis-cli -p 26379
连接成功后运行如下命令
sentinel master mymaster
2、故障验证:master宕机
ps -ef|grep [r]edis kill -9 PID
查看日志
[7014] 11 Jan 19:43:41.463 # +sdown master mymaster 127.0.0.1 6000 [7014] 11 Jan 19:46:42.379 # +switch-master mymaster 127.0.0.1 6000 127.0.0.1 6001
master切换了,当6000端口的这个服务重启的时候,他会变成6001端口服务的slave。
因为sentinel在切换master的时候,把对应的sentinel.conf和redis.conf文件的配置修改。
期间我们还需要关注的一个问题:sentinel服务本身也不是万能的,也会宕机,所以我们还得部署sentinel集群,象我这样多启动几个sentinel。
注意这个配置:
sentinel monitor mymaster 127.0.0.1 6000 2 //这个后面的数字2,是指当有两个及以上的sentinel服务检测到master宕机,才会去执行主从切换的功能。