事务、事件(文件、时间、调度和执行)、复制、分片(范围、哈希)、简单的论坛系统分析
1. 事务
一个事务包含了多个命令,服务器在执行事务期间,不会改去执行其它客户端的命令请求。
事务中的多个命令被一次性发送给服务器,而不是一条一条发送,这种方式被称为流水线。
- 它可以减少客户端与服务器之间的网络通信次数从而提升性能。
Redis 最简单的事务实现方式是使用 MULTI 和 EXEC 命令将事务操作包围起来。
2. 事件
Redis 服务器是一个事件驱动程序。
2.1 文件事件
服务器通过套接字与客户端或者其它服务器进行通信,文件事件就是对套接字操作的抽象。
Redis 基于 Reactor 模式开发了自己的网络事件处理器,使用 I/O 多路复用程序来同时监听多个套接字,并将到达的事件传送给文件事件分派器,分派器会根据套接字产生的事件类型调用相应的事件处理器。
2.2 时间事件
服务器有一些操作需要在给定的时间点执行,时间事件是对这类定时操作的抽象。
时间事件又分为:
- 定时事件:是让一段程序在指定的时间之内执行一次;
- 周期性事件:是让一段程序每隔指定时间就执行一次。
Redis 将所有时间事件都放在一个无序链表中,通过遍历整个链表查找出已到达的时间事件,并调用相应的事件处理器。
2.3 事件的调度与执行
服务器需要不断监听文件事件的套接字才能得到待处理的文件事件,但是不能一直监听,否则时间事件无法在规定的时间内执行,因此监听时间应该根据距离现在最近的时间事件来决定。
事件调度与执行由 aeProcessEvents 函数负责,伪代码如下:
def aeProcessEvents():# 获取到达时间离当前时间最接近的时间事件time_event = aeSearchNearestTimer()# 计算最接近的时间事件距离到达还有多少毫秒remaind_ms = time_event.when - unix_ts_now()# 如果事件已到达,那么 remaind_ms 的值可能为负数,将它设为 0if remaind_ms < 0:remaind_ms = 0# 根据 remaind_ms 的值,创建 timevaltimeval = create_timeval_with_ms(remaind_ms)# 阻塞并等待文件事件产生,最大阻塞时间由传入的 timeval 决定aeApiPoll(timeval)# 处理所有已产生的文件事件procesFileEvents()# 处理所有已到达的时间事件processTimeEvents()
将 aeProcessEvents 函数置于一个循环里面,加上初始化和清理函数,就构成了Redis 服务器的主函数,伪代码如下:
def main():# 初始化服务器init_server()# 一直处理事件,直到服务器关闭为止while server_is_not_shutdown():aeProcessEvents()# 服务器关闭,执行清理操作clean_server()
从事件处理的角度来看,服务器运行流程如下:
3. 复制
通过使用 slaveof host port 命令来让一个服务器成为另一个服务器的从服务器。
一个从服务器只能有一个主服务器,并且不支持主主复制。
3.1 连接过程
- 主服务器创建快照文件,发送给从服务器,并在发送期间使用缓冲区记录执行的写命令。快照文件发送完毕之后,开始向从服务器发送存储在缓冲区中的写命令;
- 从服务器丢弃所有旧数据,载入主服务器发来的快照文件,之后从服务器开始接受主服务器发来的写命令;
- 主服务器每执行一次写命令,就向从服务器发送相同的写命令。
3.2 主从链
随着负载不断上升,主服务器可能无法很快地更新所有从服务器,或者重新连接和重新同步从服务器将导致系统超载。
为了解决这个问题,可以创建一个中间层来分担主服务器的复制工作。
中间层的服务器是最上层服务器的从服务器,又是最下层服务器的主服务器。
4. Sentinel
Sentinel(哨兵) 可以监听主服务器,并在主服务器进入下线状态时,自动从从服务器中选举出新的主服务器。
5. 分片
分片是将数据划分为多个部分的方法,可以将数据存储到多台机器里面,这种方法在解决某些问题时可以获得线性级别的性能提升。
假设有 4 个 Reids 实例 R0,R1,R2,R3,还有很多表示用户的键 user:1,user:2,... ,有不同的方式来选择一个指定的键存储在哪个实例中。
5.1 范围分片
最简单的方式是范围分片,例如用户 id 从 0~1000 的存储到实例 R0 中,用户id 从 1001~2000 的存储到实例 R1 中,等等。
- 但是这样需要维护一张映射范围表,维护操作代价很高。
5.2 哈希分片
使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道应该存储的实例。
5.3 根据执行分片的位置,可以分为三种分片方式:
- 客户端分片:客户端使用一致性哈希等算法决定键应当分布到哪个节点。
- 代理分片:将客户端请求发送到代理上,由代理转发请求到正确的节点上。
- 服务器分片:Redis Cluster。
6. 一个简单的论坛系统分析
该论坛系统功能如下:
- 可以发布文章;
- 可以对文章进行点赞;
- 在首页可以按文章的发布时间或者文章的点赞数进行排序显示。
6.1 文章信息
文章包括标题、作者、赞数等信息,在关系型数据库中很容易构建一张表来存储这些信息,在 Redis 中可以使用 HASH 来存储每种信息以及其对应的值的映射。
Redis 没有关系型数据库中的表这一概念来将同种类型的数据存放在一起,而是使用命名空间的方式来实现这一功能。
- 键名的前面部分存储命名空间,后面部分的内容存储 ID
- 通常使用 : 来进行分隔。例如下面的 HASH 的键名为 article:92617,
- 其中 article 为命名空间,ID 为 92617。
6.2 点赞功能
当有用户为一篇文章点赞时,除了要对该文章的 votes 字段进行加 1 操作,还必须记录该用户已经对该文章进行了点赞,防止用户点赞次数超过 1。
可以建立文章的已投票用户集合来进行记录。
为了节约内存,规定一篇文章发布满一周之后,就不能再对它进行投票,而文章的已投票集合也会被删除,可以为文章的已投票集合设置一个一周的过期时间就能实现这个规定。
6.3 对文章进行排序
为了按发布时间和点赞数进行排序,可以建立一个文章发布时间的有序集合和一个文章点赞数的有序集合。
(下图中的 score 就是这里所说的点赞数;下面所示的有序集合分值并不直接是时间和点赞数,而是根据时间和点赞数间接计算出来的)
事务、事件(文件、时间、调度和执行)、复制、分片(范围、哈希)、简单的论坛系统分析相关推荐
- 文件时间信息在测试中的应用
1 简介 文件时间信息在测试中也有妙用- 通过记录模块运行前后的文件时间信息来识别运行前后发生变化的文件,从而识别模块运行前后的新增文件.删除的文件和内容发生变化的文件. 利用识别出来的发生变化的文件 ...
- Redis事件-文件事件、时间事件、事件调度与执行
文件事件.时间事件.事件调度与执行 概述 文件事件 文件事件处理器的构成(重要!!!) 事件类型(读事件 和 写事件) 文件事件相关API I/O多路复用程序的实现(重要!!!) 文件事件处理器(重要 ...
- linux 按日期复制文件夹,linux根据文件时间复制
将yourdir目录下修改时间一天以内的文件复制到destdir下: find /yourdir -mtime -1 -type f -exec cp {} /destdir \; 注意,后面的\;不 ...
- linux调度不执行,linux crond.d定时调度执行一段时间后不执行
问题一:/etc/cron.d下的定时任务执行一段时间后不执行 背景:在/etc/cron.d下加了一个定时任务,名为dispute_cron(使用root用户编辑),内容: 28 15 * * * ...
- linux复制文件带系统时间,不同方法/系统下复制文件时新文件的日期区别,以及查看文件创建时间、修改时间、访问时间的方法...
1:1 格拉摩根的洛斯里克城.有一个狗头人.名叫唯一丢人.是Paradox的伯爵.任天堂的主宰.育碧的bug.波兰蠢驴的打桩机. 1:2 他有三个妻.一名Windows.一名Linux.一名MacOS ...
- 如何使用损坏或删除SQL Server事务日志文件重建数据库
This is the last article, but not the least one, in the SQL Server Transaction Log series. In this s ...
- Mysql复习计划(一)- 字符集、文件系统和SQL执行流程
Mysql复习计划(一)- 字符集.文件系统和SQL执行流程 前言 一. Mysql字符集 1.1 Mysql5.7和8.0的默认字符集 1.1.1 修改默认的字符集 1.1.2 修改已有库表的字符集 ...
- Spring中的时间调度,定时任务
一 简单的线程方式周期执行 所谓线程式就是规定了和thread类似的timer类每隔一段时间(自己在配置文件中定义的时间)run方法就会被执行一次,所以他是一个单线程类首先需要了解的是他继承自java ...
- linux新建脚本文件,linux shell脚本编程2—修改文件时间和创建新文件即touch命令的使用...
在使用ls命令时,每个文件在Linux下面都会记录3个主要的修改时间: modification time(mtime,修改时间):当该文件的"内容数据"更改时,就会更新这个时 ...
最新文章
- 任正非督战:华为强攻公有云业务 竞争残酷
- iOS-改变UITextField的Placeholder颜色的三种方式
- Hive表路径修改和分区表数据加载命令
- tp5 excel 导入 mysql_TP5框架下MySQL通过LOAD DATA INFILE批量导入数据详细操作
- kaggle中zillow比赛中模型融合的方法及其代码
- java如何让线程等待_如何使Java线程等待另一个线程的输出?
- python运维工程师招聘_【python自动化运维工程师工资】图灵学院2020年python自动化运维工程师工资待遇-看准网...
- 【LeetCode】拓扑排序
- 2017.4.16 阶乘之和 思考记录
- 眼儿媚·迟迟春日弄轻柔 [宋] 朱淑真
- JNI中,getBytes()最好指明UTF-8
- 计算机形导论形考作业答案,计算机导论形考
- Delphi版 熊猫烧香源码
- java中UUID类生成32位随机数(附加 6 位随机数)
- 系统架构设计师:分布式系统(中间件技术)
- 分布式技术原理(一):分布式的三围
- Guzzle中的异步请求
- 部门来了个卷王之王,真的让人奔溃
- Java中存取Rtf文件
- ESP1020E汉王签字屏API版 支持红色笔迹
热门文章
- 搭建MongoDB分片集群
- NB-IOT终端技术新突破 中兴微电子加快IoT布局
- sqlite数据库的基本增删改查操作
- 尽管普通的sql语句代码可以实现数据插入的操作,但是更好的代码应该是参数的方式:...
- 2.1 网站防******与企业虚拟化需求分析
- 从Windows到Linux
- Java项目目录结构与解析
- Spring IOC注入Map接口小技巧
- 【网址收藏】Hadoop3.2.1 【 YARN 】源码分析 : ResourceLocalizationService解析
- Dockerfile自定义tomcat镜像