摘要:
本文是介绍MySQL数据库InnoDB存储引擎重做日志漫游00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC)。- 事务的原子性(Atomicity)事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在执行的过程中发生了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。- 原理 Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方 (这个存储数据备份的地方称为Undo Log)。然后进 阅读全文
摘要:
安装MySQL后,配置文件my.cnf在 /MySQL安装目录/share/mysql目录中,该目录中还包含多个配置文件可供参考,有my-large.cnf ,my-huge.cnf, my-medium.cnf,my-small.cnf,分别对应大中小型数据库应用的配置。win环境下即存在于MyS... 阅读全文
摘要:
关于软中断上一篇文章有提到,这一篇文章就记一点关于tasklet的东西吧tasklet是一种特殊的软中断,一般挂在中断号为0和5的中断向量上。tasklet也作为一种可延迟的中断存在,为什么这样说,看一张图片吧,转的tasklet的队列同样是挂载到中断向量中的,只不过tasklet不同于其他中断的是它是一个任务队列。也就是说如果这个中断任务不是很实时的,只需要挂载到tasklet的队列中去,自然会处理到它的。tasklet节点的数据结构如下struct tasklet_struct{ struct tasklet_struct *next; unsigned long ... 阅读全文
摘要:
中断过程简单来说就是一种CPU 与硬件沟通的方式中断分为两个过程,中间以中断控制器作为分隔。上半部分即中断上半部,下半部分为中断下半部。上半部分大部分为说说的硬件中断,下半部分为软中断。硬件中断通常由真实物理设备产生的脉冲信号作为信号源,也就是说这里的物理设备与中断控制器沟通方式是通过物理电信号来做的。软件中断由中断控制器负责统一调度,通常硬件设备产生信号,这个信号带有中断号发送给中断控制器,中断控制器轮训收到的信号来调用对应的中断处理程序。直观一点来看:通过shell> cat /proc/interrupts 可以查看到当前系统的软中断列表和对应的中断号从左到右依次表示:中断号,对应 阅读全文
摘要:
今天看了一下Go语言,在讲到以往其他语言的异常的时候,Go采用了不同的方式Panic 函数类似于抛出一个异常,这个异常会中断当前的执行函数在 defer 的延迟执行环境中,调用 recover() ,如果 recover() 返回的是 nil表示正常执行,如果非 nil 表示这个 defer延迟环境中”捕获“到了这个 panicrecover() 函数只有在 defer 包裹的执行代码块中能够使用。func throwsPanic( raisefunc func() ) (b bool){ defer func(){ if x:= recover(... 阅读全文
摘要:
方法一: # /etc/init.d/mysql stop # mysqld_safe --user=mysql --skip-grant-tables --skip-networking & # mysql -u root mysql mysql> update user set password=password('newpassword') where user='root'; mysql> flush privileges; mysql> quit # /etc/init.d/mysql restart # mysql -uro 阅读全文
摘要:
引言:Nginx模块提供了upstream(上游服务器)的异步回调处理模块开发,以memcached 模块为例commands结构的初始化为相应的命令添加回调函数,用来处理 memcached_pass 这个命令 1 static ngx_command_t ngx_http_memcached_commands[] = { 2 3 { ngx_string("memcached_pass"), 4 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, 5 ngx_http_memcached_pass, ... 阅读全文
摘要:
概述系统性能一直是一个受关注的话题,如何通过最简单的设置来实现最有效的性能调优,如何在有限资源的条件下保证程序的运作,ulimit 是我们在处理这些问题时,经常使用的一种简单手段。ulimit 是一种 linux 系统的内键功能,它具有一套参数集,用于为由它生成的 shell 进程及其子进程的资源使用设置限制。本文将在后面的章节中详细说明 ulimit 的功能,使用以及它的影响,并以具体的例子来详细地阐述它在限制资源使用方面的影响。ulimit 的功能和用法ulimit 功能简述假设有这样一种情况,当一台 Linux 主机上同时登陆了 10 个人,在系统资源无限制的情况下,这 10 个用户同时 阅读全文
摘要:
引言:上一章讲了关于HTTPServer的原理,这一次通过分析源码来了解更多的细节看看HTTPServer类的组织结构:HTTPServer的主要工作一.提供了一些基础的比如说listen,bind此类共有操作二.完成了一个 _handle_events()的公有回调函数,此函数是 IOLoop的基础,此函数为每一个连接创建一个单独的 IOStream 对象三.start函数,启动HTTPServer,并设置相应的参数(如根据CPU个数来设置进程数等)从HTTPServer类的构造函数可以看出,最重要的参数是设置回调函数,此回调函数用于处理request对象每次有HTTP的请求,都会通过HTT 阅读全文
摘要:
1.tornado简介:http://www.cnblogs.com/Bozh/archive/2012/07/17/2596458.html 2.tornado 网络层IOLoop:http://www.cnblogs.com/Bozh/archive/2012/07/18/2597114.htm 阅读全文
摘要:
引言:第四章讲解的有些乱,主要是代码太长了,而且还是在一章就讲完了,所以我决定将IOStream上层的HTTPServer类分作几章来讲,不按照代码顺序在讲完了IOLoop和IOStream后就知道,第一次在监听套接口的时候需要用到IOLoop,然后创建一个IOStream对象,然后以后的IO操作都由IOStream对象完成所以在上层的HTTP协议处理中,tornado定义了一个HTTPConnection类这个类主要完成的工作就是完成对下,完成HTTP数据包的传输,对上层HTTPserver提供解析后的request对象那么他们之间的工作模式是怎样的呢看看Demo import... 阅读全文
摘要:
引言:在分析了部分IOLoop,了解了其工作原理后,就可以看看建立在IOLoop上层的IOStream。IOStream主要提供的功能就是异步的读写操作。IOStream提供的接口有几个:1.read_bytes(bytes,callback)这个接口就是在有固定的字节的数据到来的时候调用回调函数2.read_until(delimiter,callback)这个接口的作用是在读取到固定的字符序列结尾后调用回调函数 callback3.write(data)异步写,就是将数据拷贝到应用层的缓冲区,由IOLoop下层统一调度看看源码的Demo from tornado import... 阅读全文
摘要:
引言:由于都是在工作当中抽出时间看源代码,所以更新速度比较慢,但是还是希望通过对好的源码的分析和探讨,大家相互学习,发现不好的地方共同讨论。上次讲了IOLoop中的几个重要的方法,inistance() 和 add_handler() .. 今天看看Demo中一个最重要的方法,start(),顺带用stop()收尾 def start(self): """Starts the I/O loop. The loop will run until one of the I/O handlers calls stop(), which will mak... 阅读全文
摘要:
引言:上一章起了个头,讲了tornado的源码结构和IOLoop的简单Demo,这一章就IOLoop类的方法来看看IOLoop提供了哪些功能。看看IOLoop的类组织结构 |---IOLoop ---__init__(self, impl=None) ---instance(cls) ---initialized(cls) ---add_handler(self, fd, handler, events) ---update_handler(self, fd, events) ---remove_handler(self, fd) ---set_blocking_s... 阅读全文
摘要:
引言: tornado是由Facebook开源的一个服务器“套装",适合于做python的web或者使用其本身提供的可扩展的功能,完成了不完整的wsgi协议,可用于做快速的web开发,封装了epoll性能较好。文章主要以分析tornado的网络部分即异步事件处理与上层的IOstream类提供的异步IO,其他的模块如web的tornado.web 以后慢慢留作分析。首先说明几点问题:(1)文章供大家交流使用,如果有错误,发扬开源精神,共同交流(2)文章不加以说明,均以Linux环境为例(3)如果有epoll,tornado默认使用epoll,这里就不分析select和KQueue了(4 阅读全文
摘要:
引言:最近实习由于项目需要,为了追求稳定性加上烤鱼利用Nginx本身提供的优秀的基础设施,使用了Nginx提供的一些扩展功能来做Nginx本身的开发。Nginx提供了很强的可以自己定制扩展功能的“插件式”扩展,在需要加钩子的地方构造回调函数来完成相应功能(说起来容易做起来难)。Nginx可以提供三种方式的模块扩展:1.Handler方式处理HTTP请求2.Filter方式对于输出的HTTP做过滤,可以加解密或其他功能等3.Load Balancer,作为HTTP方向代理时候的负载均衡所用由于项目原因,暂时使用的是Handler方式,不过大多数场景下也是使用了Handler方式Nginx处理HT 阅读全文
摘要:
引言:学习python近两年,谈谈我对于python的一点小理解,也从一些方面谈谈自己微薄的想法,也就是我为什么学习python这里我不讨论python的一些有用的库或者框架,只从语言本身,最小支持的情况下谈论这门语言本身。语言的发展都是越来越接近Lisp,这也是这门语言伟大的原因。下面我罗列一下我学习python的原因:一.多编程范式python是一门多范式的编程语言,所谓的过程式,面向对象和函数式的结合。大部分人接触编程语言都是从过程式开始的,原因是因为过程式的程序方式与计算机运行方式是统一的,指令序列与运行过程是统一的如典型的C,我也是从C开始学习的,过程式的程序语言设计编写程序较为简单 阅读全文
摘要:
作为读书笔记使用:线性递归:1 fac(0) -> 1;2 fac(N) -> N*fac(N-1).尾递归:1 fac(0,Sum) -> 2 Sum;3 fac(N,Sum) -> 4 fac(N-1,Sum*N).尾递归定义: 函数最后一步调用自身,即最后一行代码一定是对于自己的一个递归调用。Erlang尾递归这样带来的好处是可以让编译器做到将递归优化,转化为跳转指令而不是,可以防止栈空间爆炸。尾递归通常的做法是将中间状态加入到参数中,还可以防止共享变量的问题。这也是传说中的中间状态python中对于尾递归的优化我还不得而知,Erlang对于线性递归做到了一定的优 阅读全文
摘要:
引言:前几天看了一点InfoQ上大神们很多的总结,服务编程范式以这样的方式进化多进程--->多线程--->非阻塞--->协程。说说协程,找了一些关于GreenLet的资料,协程也称作微线程,是比线程还小的一种执行体。线程确实执行体就是一个函数,在用户空间看来,但是在内核中线程也是一个进程,LWP所谓的轻量级进程,线程也存在自己的上下文运行环境。协程不同于线程的是,线程是抢占式的调度,而协程是协同式的调度,也就是说,协程需要自己做调度。看看一个简单的消费者&生产者模型的python代码:def coroutine(func): def ret(): f = func() 阅读全文
摘要:
Kerberos协议: Kerberos协议主要用于计算机网络的身份鉴别(Authentication), 其特点是用户只需输入一次身份验证信息就可以凭借此验证获得的票据(ticket-granting ticket)访问多个服务,即SSO(Single Sign On)。由于在每个Client和S 阅读全文
摘要:
作为一些感悟就留着自己珍藏吧,不发到首页了。个人觉得软件设计就应该像搭积木,或者说是俄罗斯方块俄罗斯方块的每一个块都可以看做软件设计中的模块,但是方块的形状是不同的。需要将整个软件设计的良好,我们应当遵循的就是在设计模块过程中模块之间的耦合性。堆俄罗斯方块的方式可以让我们在设计过程中设计良好的接口标准,达到模块之间的耦合减小的同时,让模块之间功能独立,依赖性更低,而且可以将软件的层次划分的更清楚。软件层次是模块与模块之间的中间层的一种抽象,可能在模块与模块之间,也有可能是多个模块与多个模块之间,对于方式是N:M形式。我比较倾向于C使用回调,C++使用接口+多态的方式来完成功能依赖的解耦。pyt 阅读全文
摘要:
引言:前面的一系列文章都在说了事件模型,也就是简单的做一个介绍,然后贴出了一些代码作为Demo,上次说到了在反应堆中的超时管理。今天就来说说关于利用最小堆来管理超时的问题。NOTICE:判断一个事件是否超时的方法是, 事件超时时间 减 当前时间 ,如果大于零,说明没有超时,如果小于零,说明该事件超时了。一般做法是怎样来管理所有的超时事件呢?以前的用法都是利用链表来保存所有的超时事件,轮训查看是否事件超时,若超时就采取相应的措施,比如移除事件等。后来的Nginx和libevent采取了更好的措施,Nginx是利用红黑树来管理,而libevent是利用最小堆来管理。今天的主题是最小堆,所以下面的内 阅读全文
摘要:
引言:持续更新了一段时间的博客,今天把最后一点部分加上,一个简单的反应堆的实现,基于epoll,工作过程上一篇博文已经有所介绍。需要再次提到的就是关于反应堆的使用方式:注册事件(为需要监听的fd加入回调函数)----->将事件加入反应堆------>开始事件循环------>事件发生,调用回调函数第一次加入的描述符可以为监听描述符,即由 socket() 函数创建,当这个描述符有事件发生,意味着有新的连接的到来,调用回调函数handler_accept() 其中这个函数里面涉及到调用 accept()系统调用和为这个新连接分配实例,然后设置这个连接的回调函数,即 handle 阅读全文
摘要:
引言:前面一章简单介绍了关于epoll 的使用方式,这一章介绍一下一个简单的反应堆模型,没有实现超时机制的管理。最主要的是要介绍一下关于异步事件反应堆的设计方式。反应堆的模型图在上一张可以看到,但是那个是盗来的一张图,twisted 的反应堆。今天给不熟悉这个部分的朋友介绍一下基于 epoll 的反应堆,过程类似于libevent.反应堆可以提供几个操作:(0)创建一个反应堆:mc_event_base_t * mc_base_new(void) ;返回一个操作句柄. (1)为某一个需要监听的文件描述符加入回调函数,并注册事件类型。int mc_event_set( mc_event_t *. 阅读全文
摘要:
引言:上一篇说到了线程池方式来处理服务器端的并发,并给出了一个线程池的方案(半同步,半异步方式)。各有各的好处吧,今天来讲讲关于非阻塞的异步IO。说到异步IO,其实现在很难实现真正的异步,大部分情况下仍然需要阻塞在某个多路复用函数,比如select 或者 epoll 上,得到就绪描述符,然后调用注册在相应描述符上的回调函数。这种方式是现在的反应堆设计的基本思路。我截取一段反应堆模型的图给大家看看。这个图是截取至 python的 twisted 服务器的反应堆文章介绍,但是大致和我们需要的理念一样。事件循环阻塞查看描述符是否就绪,当就绪后返回可读或可写的描述符,也有可能带外数据或者出错等情况。因 阅读全文
摘要:
引言:上篇文章说到了多进程并发式的服务端模型,如上一篇文章所述,进程的频繁创建会导致服务器不堪负载,那这一篇博客主要讲述的是线程模型和线程池的方式来提高服务端的负载能力。同时比较一下不同的模型的好处与坏处。(如果不加以说明,我们都是考虑开发是基于GNU/Linux的)在Linux下创建一个线程的方式很简单,pthread_create() 函数来创建线程,其中的一个参数的回调函数,也就是线程本身的执行体函数。void *thread_entry( void * args );这里不过多的强调怎样利用线程等来创建执行体以及其他的系统调用怎样使用的。那么,在服务端的线程使用方式一般为三种种:(1) 阅读全文
摘要:
引言:上篇文章讲到同步阻塞迭代式的进程方式,这篇文章讲述一下关于处理单进程阻塞于系统调用的情况。使用方式是多进程的方式,可以减少很大一部分的因为进程阻塞所带来的服务器无法响应问题。基本思想是这样,如上篇文章所述,在单进程阻塞在read() 系统调用的时候,会导致服务器无法响应其他的连接请求,那么我们可以通过在服务器fork() 出很多子进程来处理业务,而主进程负责 accept() 其他的客户连接。主体框架是这样:for(;;){ fd = accept(...); ret = fork() ; switch( ret ) { case -1 : do_err_handler()... 阅读全文
摘要:
引言:似乎现在阻碍服务端大部分情况下都属于IO瓶颈,硬盘的转速等,而计算的瓶颈大部分云端计算采用分布式计算,如基于GFS的MapReduce模型,网格计算或者其他的一些分布式处理。所以,现在服务端的服务衡量指标基本集中在并发量,QPS,响应速度,稳定性等。其中一部分也不乏大量的计算,属于CPU密集型的,根据业务的不同应该做相应的调整。今天的话题是浅谈一下几种常用的IO模型。理解IO 模型是网络编程的重点。最简单的同步迭代IO模型:核心代码就是这样,这里我们假设前面的监听套接口已建立。即已绑定套接口,并调用了listen()函数。同步迭代IO大致如下,我们假设现在的模型是这样的,服务端监听客户端 阅读全文
摘要:
引言:昨天写了一个简单的通过字典树来索引比较大的字母集合的程序。通过字典树,确实能够大大减少查询时间,是一种不错的字母表的匹配方案。这里我就拿出来分享一下。(ps:英文单词集大概有35W+ 条记录,数据量确实不小,在操作中为了简化,去除了英文单词中的 " ' " "-" 等等,作为字典树,必须以26 个英文字母作为树的子节点的索引。)看看字典树的结构定义:typedef struct _dict_tree_{ struct _dict_tree_ * dt[TREENODENUM]; char c ; char flag ;}DT ;dt 指针指 阅读全文
摘要:
关于断言,可以作为一种很强大的调试方式或者程序运行时的错误诊断但是断言也不是适合于各种地方,服务器软件和嵌入式程序一般不适用,断言会强制中断正在运行的程序,对于服务器等程序来说,将会是一个灾难。加上,断言会加剧CPU 的负载,其中会调用一些函数。作为调试时使用断言是个不错的选择一般断言:#ifndef NDEBUG assert( conditon ) ;#endif这样,你的断言会在没有定义NDEBUG 的时候检测是否assert(..)中的表达式为真,如果不为真,将终止程序但是,作为一种调试方式,assert()一般不用于判断用户的输入,而是断言程序在某个时刻的状态一定为真,当然,终止程序 阅读全文
摘要:
将依赖于用户输入的数据都看做不安全数据:1.空指针2.字符串的长度3.在限定有输入时的长度 的符号类型4.输入时候的符号5.严格判断输入的类型与所处理的数据的类型是否符合6.禁止格式化输出一般程序员在编写一个函数的时候,只会注意到函数的实现功能,往往忘记了在函数编写过程当中的一些安全因素其实这些东西才是一般大型的公司考察一个程序员是否成熟的标志,当然,只是一方面1:空指针一般在接受一个参数的时候,如果该参数是一个指针或者字符串,当然这里的字符串是传统的C 的char *string 类型你是否会考虑到可能传入的是一个空指针,如果函数中应用了一个空指针作为数据,将会导致程序因非法内存访问而终止所 阅读全文
摘要:
引言:总所周知,NoSQL,Memcached等作为Key—Value 存储的模型的数据路由都采用Hash表来达到目的。如何解决Hash冲突和Hash表大小的设计是一个很头疼的问题。借助于Radix树,我们同样可以达到对于uint32_t 的数据类型的路由。这个灵感就来自于Linux内核的IP路由表的设计。作为传统的Hash表,我们把接口简化一下,可以抽象为这么几个接口。void Hash_create( size_t Max );int Hash_insert( uint32_t hash_value , value_type value ) ;value_type *Hash_get( u 阅读全文
摘要:
引言:应用级别的内存分配器的作用主要在于减少malloc函数的调用,降低系统的内存碎片。作为高性能的服务器,一般都会有自己的内存分配方案。slab作为一款Linux内核的经典内存分配方式,应用在很多的应用级别的软件上,比如说Memcached 等。 今天的主题就分享一下最近写的slab的一个简单的Demo,在于分享,代码有些粗糙,比如缺少对于内存字节的比例因子,缺少关于内存不足的情况下重分配等。不过各种应用各有各自的用途,在实现某些cached操作的软件中,由于带有LRU 算法等,在内存快使用完后就采取淘汰策略,所以不一定在内存不足的情况下重新给操作系统分配。Slab内存分配器原理: ... 阅读全文