当前位置: 首页 > news >正文

网站策划方案实例营口网站开发

网站策划方案实例,营口网站开发,海报设计图片手绘图,软件技术开发合同范本写在前面 Redis作为我们日常工作中最常使用的缓存数据库#xff0c;其重要性不言而喻#xff0c;作为普通开发者#xff0c;我们在日常开发中使用Redis#xff0c;主要聚焦于Redis的基层数据结构的命令使用#xff0c;很少会有人对Redis的内部实现机制进行了解#xff0c… 写在前面 Redis作为我们日常工作中最常使用的缓存数据库其重要性不言而喻作为普通开发者我们在日常开发中使用Redis主要聚焦于Redis的基层数据结构的命令使用很少会有人对Redis的内部实现机制进行了解对于我而言也是如此但一直以来我对于Redis的内部实现都很好奇它为什么会如此高效本系列文章是旨在对Redis源代码分析拆解通过阅读Redis源代码了解Redis基础数据结构的实现机制。 关于Redis的源码分析已经有非常多的大佬写过相关的内容最为著名的是《Redis设计与实现》对于Redis源码的分析已经非常出色本系列文章对于源码拆解时并不会那么详细相信大部分读者应该不是从事Redis的二次开发工作对于源码细节过于深入会陷入细节的泥潭这是我在阅读源码时尽量避免的我尽量做到对大体的脉络进行梳理讲清楚主干逻辑细节部分如果读者有兴趣可以自行参阅源码或相关资料。 本系列源代码基于Redis 3.2.6 前言 在上两篇中 浅析Redis①命令处理核心源码分析(上) 浅析Redis②命令处理之epoll实现(中) 我们大致了解了Redis客户端命令请求的处理流程在整个流程中我们了解了Redis是如何处理来自客户端的命令请求epoll的执行逻辑我们还有最后一个问题没有解释Redis是如何将数据写回Client端的 本篇我们就围绕第一个问题寻找答案继续看Redis客户端命令请求的处理流程。 Redis数据返回Client端流程 Redis在命令处理时在命令执行的末尾都会调用一个addReply()这里我们以最简单的STRING get为例 t_string.c getGenericCommand() int getGenericCommand(client *c) {robj *o;// 从字典中查询数据if ((o lookupKeyReadOrReply(c,c-argv[1],shared.nullbulk)) NULL)return C_OK;// 将数据返回Clientif (o-type ! OBJ_STRING) {addReply(c,shared.wrongtypeerr);return C_ERR;} else {addReplyBulk(c,o);return C_OK;} }void addReplyBulk(client *c, robj *obj) {addReplyBulkLen(c,obj);addReply(c,obj);addReply(c,shared.crlf); }继续看addReply()的实现 networking.c addReply() void addReply(client *c, robj *obj) {if (prepareClientToWrite(c) ! C_OK) return;// 核心将数据写入内存缓存区等待后续流程处理写回Client Socketif (sdsEncodedObject(obj)) {if (_addReplyToBuffer(c,obj-ptr,sdslen(obj-ptr)) ! C_OK)_addReplyObjectToList(c,obj);} else if (obj-encoding OBJ_ENCODING_INT) {if (listLength(c-reply) 0 (sizeof(c-buf) - c-bufpos) 32) {char buf[32];int len;len ll2string(buf,sizeof(buf),(long)obj-ptr);if (_addReplyToBuffer(c,buf,len) C_OK)return;}obj getDecodedObject(obj);if (_addReplyToBuffer(c,obj-ptr,sdslen(obj-ptr)) ! C_OK)_addReplyObjectToList(c,obj);decrRefCount(obj);} else {serverPanic(Wrong obj-encoding in addReply());} }上述流程是string get命令执行后数据处理的流程可以发现Redis并没有将数据直接返回Client端而是将数据写入了一个叫做缓冲区的内存区域那么缓冲区是什么 Redis的内存缓冲区 在 Redis 中缓冲区buffer是用于存储数据的内存区域。Redis 使用缓冲区来管理数据的读取、写入和传输过程。 Redis 的缓冲区主要有两个方面的应用 输入缓冲区Input Buffer当 Redis 接收到客户端发送的命令请求时会先将请求数据存储在输入缓冲区中然后再进行解析和处理。输入缓冲区用于临时存储从网络或其他输入源接收到的原始数据。输出缓冲区Output Buffer当 Redis 响应客户端的命令请求时会先将响应数据存储在输出缓冲区中然后再发送给客户端。输出缓冲区用于临时存储待发送的数据。 缓冲区在 Redis 中的作用是提高数据的处理效率和性能。通过使用缓冲区Redis 可以批量读取和写入数据减少了频繁的系统调用和网络传输开销。此外缓冲区还可以用于临时存储数据以便进行数据的加工和处理。 需要注意的是Redis 缓冲区大小是有限的它受到配置参数 client-output-buffer-limit 和 client-query-buffer-limit 的影响。 如果缓冲区已满而输入或输出数据仍在不断到达则可能导致连接被拒绝或数据丢失。 因此在高并发或大数据量的场景中需要根据实际情况调整缓冲区大小以保证系统的稳定性和性能。 OK命令处理部分流程结束我们把逻辑拉回到main函数中聚焦aeMain() ae.c aeMain() void aeMain(aeEventLoop *eventLoop) {eventLoop-stop 0;while (!eventLoop-stop) {if (eventLoop-beforesleep ! NULL)eventLoop-beforesleep(eventLoop);aeProcessEvents(eventLoop, AE_ALL_EVENTS);} }在前两篇中我们介绍过aeMain()这里使用一个死循环aeProcessEvents()轮询epoll是否存在就绪的事件在aeProcessEvents()之前我们需要关注beforesleep() if (eventLoop-beforesleep ! NULL)eventLoop-beforesleep(eventLoop);在轮询之前都会执行beforesleep()这个函数就是我们要关注的核心继续看beforesleep()实现 server.c beforeSleep() void beforeSleep(struct aeEventLoop *eventLoop) { .... .... 此处省略部分非核心代码 .... /* Write the AOF buffer on disk */flushAppendOnlyFile(0);// 将数据写回ClienthandleClientsWithPendingWrites(); }networking.c handleClientsWithPendingWrites() int handleClientsWithPendingWrites(void) {listIter li;listNode *ln;int processed listLength(server.clients_pending_write);listRewind(server.clients_pending_write,li);while((ln listNext(li))) {......省略部分非核心代码 // 核心将数据通过socket返回Clientif (writeToClient(c-fd,c,0) C_ERR) continue;// 还有部分数据没有写完加入epoll等待异步执行if (clientHasPendingReplies(c) aeCreateFileEvent(server.el, c-fd, AE_WRITABLE,sendReplyToClient, c) AE_ERR){// 释放内存freeClientAsync(c);}}return processed; }上述代码是执行数据返回Client的核心逻辑可以参见代码注释令人疑惑的部分是为什么这段代码中writeToClient()可能会执行两次 原因如下 第一次调用 writeToClient() 是为了尝试向客户端套接字写入数据。这里的目的是将服务器待发送的数据写入到套接字缓冲区中以便后续通过网络发送给客户端。如果写入成功则会继续判断该客户端是否还有待发送的数据。 第二次调用 writeToClient() 是在判断客户端是否还有待发送的数据后执行的。如果客户端仍然有待发送的数据那么说明套接字的发送缓冲区已满无法一次性将所有数据发送出去。此时为了确保后续的数据能够被及时发送需要将该客户端的套接字注册到可写事件上以便在套接字可写时继续发送剩余的数据。 需要注意的是第二次调用 writeToClient() 并不会立即执行数据的发送而是在套接字变为可写时由事件循环机制触发相应的写入操作。 这样可以避免在套接字无法写入数据时出现阻塞的情况提高服务器的并发性能。 OK我们继续看writeToClient() 的实现逻辑。 networking.c writeToClient() int writeToClient(int fd, client *c, int handler_installed) {ssize_t nwritten 0, totwritten 0;size_t objlen;size_t objmem;robj *o;// 循环读取内存缓冲区的数据写回socket返回Client端while(clientHasPendingReplies(c)) {if (c-bufpos 0) {// 核心执行socket写回nwritten write(fd,c-bufc-sentlen,c-bufpos-c-sentlen);if (nwritten 0) break;c-sentlen nwritten;totwritten nwritten;/* If the buffer was sent, set bufpos to zero to continue with* the remainder of the reply. */if ((int)c-sentlen c-bufpos) {c-bufpos 0;c-sentlen 0;}} else {o listNodeValue(listFirst(c-reply));objlen sdslen(o-ptr);objmem getStringObjectSdsUsedMemory(o);if (objlen 0) {listDelNode(c-reply,listFirst(c-reply));c-reply_bytes - objmem;continue;}nwritten write(fd, ((char*)o-ptr)c-sentlen,objlen-c-sentlen);if (nwritten 0) break;c-sentlen nwritten;totwritten nwritten;/* If we fully sent the object on head go to the next one */if (c-sentlen objlen) {listDelNode(c-reply,listFirst(c-reply));c-sentlen 0;c-reply_bytes - objmem;}}.........省略部分非核心代码......... }.........省略部分非核心代码......... return C_OK; }writeToClient()就是核心写入的部分了这里获取redisClient对象的bufpos可以理解为缓冲区中的标记位置如果存在待写入的数据循环调用系统方法write写入socket的FD中。 write() 函数用于向文件描述符包括套接字写入数据。在这段代码中write() 函数被用于将数据写入到客户端的套接字中即向客户端发送数据。 就此Redis将数据返回Client的流程我们就了解完毕。 老规矩我们还是用一张流程图来简略描述整个过程
http://www.pierceye.com/news/534185/

相关文章:

  • 郫县网站制作wordpress搜索打钩
  • 哪些网站可以做招商广告语wordpress发文章的id怎么不连续
  • 家私网站栏目和功能需求策划网页样式库
  • 什么是网站网页主页企业电子邮箱格式
  • 金属建材企业网站建设方案用pycharm做网站
  • 重庆网站空间黄骅港一期码头潮汐表
  • 推广网站如何做做酒店网站所用到的算法
  • 最好的网站建设组织wordpress 删除google
  • 生物科技 网站模板下载在线室内设计
  • 网站兼容性问题线上设计师接单
  • 外包网站平台可以做电算化的网站
  • 教育网站设计案例学校网站设计
  • 网站建设入门教程pdf网络推广和seo
  • 闲鱼钓鱼网站怎么做百度网页版主页
  • 一次备案多个网站alexa排名查询
  • 郑州做招商的网站网站建设的流程推广方案
  • wordpress手机网站插件海口seo关键词优化
  • wordpress随机文章佛山网站优化美姿姿seo
  • 做酒类网站中铁三局最新消息
  • 网站建设教程给赚湖南岚鸿官 网英语培训学校网站建设多少钱
  • 电子商务网站的建设步骤有注册咨询公司经营范围
  • 手机端网站做app开发wordpress建站论坛
  • 四合一做网站微信公众平台怎么做微网站
  • 法治与安全做讲座网站系统工具
  • wap网站怎么做白石洲网站建设
  • 网站备案 关闭网站广州安全教育平台登录入囗
  • 做常州美食网站首页的背景图招聘网站建设费用多少
  • 制作网站需要wordpress网站的建设步骤包括什么
  • 有什么网站可以做微信支付宝支付宝闽侯县建设局网站
  • html5网站图标qq刷赞网站如何做分站