Archive for January, 2014

作者:AngryFox 分类: Uncategorized January 28th, 2014 暂无评论

#运算符的作用,可以用来连接字符串
作用域:局部变量的作用域从定义处到该过程(可以是一个复合语句也可以是一个函数)结
束.全局变量的作用域从定义处到文件结束。
能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量
定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量
scanf 函数的用法和说明
(1) 指定输入列数,系统自动截取,比如:scanf(“%3d”,&a);输入 1234;a=123;
(2) *的用法,跳过指定列数.比 scanf(“%2d%*3d%d”,&a,&b);输入 1234567,a=12,b=67;
345 被跳过。
(3) 输入时不能指定精度。
for(;;)优于while(1),不占用寄存器,而且没有判断跳转
i– 优于i++,使用自减指令循环比使用自加指令控制循环生成的代码更少1-3个字母
用移位实现乘除法运算
strcpy()函数当遇到字符串末尾的null字符(\0)时,删除该字符并结束拷贝
sizeof 是 C 语言的一种单目操作符,如 C 语言的其他操作符++、–等。它并不是函数
sizeof 操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知
存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void 类型
等。
int(4)、unsigned int(4) 、short int(2)、unsigned short(2) 、long int(8) 、unsigned long(8) 、float(4)、double(8)、long double(16) 类型的 sizeof 在 ANSI C 中没有具体规定,大小依赖于实现

编译器将内存划分成 4 个区,分别是栈区、堆区、全局/静态区、常量区。如果要
更细地划分,还可以添加一个自由存储区;把全局区看作两部分,为初始化全局区和未初始
化全局区。
1)栈 – 由编译器自动分配释放,如我们定义了一个变量,由编译器负责为它分配空间
和回收。
2)堆 – 一般由程序员通过函数(malloc/free 等)分配释放,若程序员不释放,程序结
束时可能由 OS 回收。
3)全局区(静态区)- 全局变量和静态变量的存储是放在一块的,初始化的全局变量和
静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。同
样由编译器分配释放,不过释放要等到程序结束时。
4)常量存储区 – 编译器负责管理,程序结束释放。
也就是说,C 语言中,我们实际使用到,能对值发生改变的有堆、栈和全局区,而真正
能由我们自由分配和释放的操作在堆区完成。

auto break case const continue do default double else
for enum float goto if int long register return
struct switch char extern short signed sizeof static
typedef union unsigned void volatile while

TCP连接在操作系统内核上消耗的内存多少感兴趣。socket编程方法提供了SO_SNDBUF、SO_RCVBUF这样的接口来设置连接的读写缓存,linux上还提供了以下系统级的配置来整体设置服务器上的TCP内存使用

作者:AngryFox 分类: Uncategorized January 27th, 2014 暂无评论

1.虚拟机运转的核心功能
lapi.c – Lua的API.实现Lua C API(lua_*函数)集合,C语言接口
lctype.c – C标准库中ctype相关实现
ldebug.c – 调试接口:包含访问调试钩子的函数(lua_sethook/lua_gethook/lua_gethookcount),访问运行时堆栈信息的函数 (lua_getstatck/lua_getlocal/lua_setlocal),检查字节码函数(luaG_checkopenop /luaG_checkcode),和抛出错误的函数(luaG_typeerror/luaG_concaterror /luaG_aritherror/luaG_ordererror/luaG_errormsg/luaG_runerror)
ldo.c -函数调用及栈管理,Lua的栈和调用结构。控制函数调用(luaD_call/luaD_pcall),栈增长,协同代码的同步
lfunc.c - 包装原型和闭包的辅助函数
lmem.c - 内存管理的接口.通过封装内存分配函数,实现了luaM_realloc / luaM_growaux_两个函数.
lgc.c - 垃圾回收器(内存管理)
lobject.c - 一些针对Lua对象的通用函数。 包括数据类型到字符串转换函数,纯数据相等测试函数(luaO_rawequalObj),和日志基础2(luaO_log2)
lopcodes.c - Lua虚拟机的操作符。定义所有操作符的名称和信息(使用luaP_opnames和luaP_opmodes两个表保存)
lstate.c - 全局上下文. 包括打开和关闭LUA上线文的函数(lua_newstate/lua_close)和lua线程函数(luaE_newthread/luaE_freethread)
ltm.c - 标记原语方法。实现对象访问原语方法(metathods)
lstring.c - 字符串池
ltable.c - 表操作库,Lua表实现(哈希)
lvm.c - Lua虚拟机。执行字节码(luaV_execute)。也暴漏一些lapi.c可能用到的函数(例如:luaV_concat)
lzio.c - 一个通用的带缓冲区的输入流接口

2.源代码解析以及预编译字节码
lcode.c - Lua的代码生成器。被lparser.c使用
llex.c - 词法分析器。被lparser.c使用
lparser.c - Lua语法检查器
lundump.c – 加载预编译后的Lua代码块,函数luaU_undump,加载一个预编译后的代码块;luaU_header(被luaU_undump使用的内部函数),用来检查函数头部。
ldump.c - 保存预编译后的Lua代码块。函数luaU_dump,使用预编译后的代码字符串展示一个函数

3.内嵌库
lcorolib.c - 协程库
lmathlib.c - 数学库
loslib.c - 操作系统相关库
liolib.c - 输入输入库
loadlib.c - 模块库(实现require函数,package函数)
ldblib.c - 调试库
linit.c - 实现luaL_openlibs方法,便于在C语言中加载上述模块

lbitlib.c - 位操作库
lauxlib.c - 定义所有的luaL_*函数集
lbaselib.c - 基础函数库
lstrlib.c - 字符串库
ltablib.c - 表处理库

4.可执行的解析器,字节码编译器
lua.c - Lua独立解释器
luac.c - Lua编译器(保存字节码到一个文件,也可以列出字节码)

The prefix of a external symbol indicates the module it comes from:
外部符号的前缀暗示他来自哪一个文件:
luaA_ – lapi.c
luaB_ – lbaselib.c
luaC_ – lgc.c
luaD_ – ldo.c
luaE_ – lstate.c
luaF_ – lfunc.c
luaG_ – ldebug.c
luaH_ – ltable.c
luaI_ – lauxlib.c
luaK_ – lcode.c
luaL_ – lauxlib.c/h, linit.c (public functions)
luaM_ – lmem.c
luaO_ – lobject.c
luaP_ – lopcodes.c
luaS_ – lstring.c
luaT_ – ltm.c
luaU_ – lundump.c
luaV_ – lvm.c
luaX_ – llex.c
luaY_ – lparser.c
luaZ_ – lzio.c
lua_? – lapi.c/h + luaconf.h, debug.c
luai_ – luaconf.h
luaopen_ – luaconf.h + libraries (lbaselib.c, ldblib.c, liolib.c, lmathlib.c, loadlib.c, loslib.c, lstrlib.c, ltablib.c)

作者:AngryFox 分类: Uncategorized January 25th, 2014 暂无评论
#include <stdio.h>
union ut {
    short s;
    char c[2];
}u;

int main()
{
    if(sizeof(short)==2)
    {
        u.s = 0x0102;
        if(u.c[0]==1 && u.c[1] == 2)
        {
            printf("big\n");
        }else if(u.c[0] ==2 && u.c[1] == 1)
        {
            printf("little\n");
        }
    }

    return 0;
}

什么是字节序
在不同的计算机体系结构中,对于数据(比特、字节、字)等的存储和传输机制有所不同,因而引发了计算机领域中一个潜在但是又很重要的问题,即通信双方交流的信息单元应该以什么样的顺序进行传送。如果达不成一致的规则,计算机的通信与存储将会无法进行。目前在各种体系的计算机中通常采用的字节存储机制主要有两种:大端(Big-endian)和小端(Little-endian)。这里所说的大端和小端即是字节序。

MSB和LSB
MSB是Most Significant Bit/Byte的首字母缩写,通常译为最重要的位或最重要的字节。它通常用来表示在一个bit序列(如一个byte是8个bit组成的一个序列)或一个byte序列(如word是两个byte组成的一个序列)中对整个序列取值影响最大的那个bit/byte。
LSB是Least Significant Bit/Byte的首字母缩写,通常译为最不重要的位或最不重要的字节。它通常用来表明在一个bit序列(如一个byte是8个bit组成的一个序列)或一个byte序列(如word是两个byte组成的一个序列)中对整个序列取值影响最小的那个bit/byte。
对于一个十六进制int类型整数0×12345678来说,0×12就是MSB,0×78就是LSB。而对于0×78这个字节而言,它的二进制是01111000,那么最左边的那个0就是MSB,最右边的那个0就是LSB。
大端序
大端序又叫网络字节序。大端序规定高位字节在存储时放在低地址上,在传输时高位字节放在流的开始;低位字节在存储时放在高地址上,在传输时低位字节放在流的末尾。
小端序
小端序规定高位字节在存储时放在高地址上,在传输时高位字节放在流的末尾;低位字节在存储时放在低地址上,在传输时低位字节放在流的开始。
网络字节序
网络字节序是指大端序。TCP/IP都是采用网络字节序的方式,java也是使用大端序方式存储。
主机字节序
主机字节序代表本机的字节序。一般是小端序,但也有一些是大端序。
主机字节序用在协议描述中则是指小端序。
总结
字节序只针对于多字节类型的数据。比如对于int类型整数0×12345678,它占有4个字节的存储空间,存储方式有大端(0×12, 0×34, 0×56, 0×78)和小端(0×78, 0×56, 0×34, 0×12)两种。可以看到,在大端或小端的存储方式中,是以字节为单位的。所以对于单字节类型的数据,不存在字节序这个说法。

Big-endian和little-endian是描述排列存储在计算机内存里的字节序列的术语。

Big-endian是一种大值的一端(序列中更典型值)存在前面(在最小的存储地址)的顺序。Little-endian是一种小值的一端(序列中较不典型的值)存储在前的顺序。比如,在Big-endian的电脑中,需要两个字节把十六位数4F52当作4F52存在存储器中(如果4F存在存储地址1000中,比如说,52将存在1001中)。在little-endian系统里,将被存为524F(52存在存储地址1000中,比如说,4F将存在1001中)。

IBM的370主机,多数基于RISC计算机,和Motorola的微处理器使用big-endian方法。TCP/IP也使用big-endian方法(因此big-endian方法也叫做网络编码)。对于人来说我们的语言都是从左到右的习惯方式。这看上去似乎被认为是自然的存储字符和数字方式-你同样也希望以同样的方式出现在你面前。我们总的许多人因此也会认为big-endian是流行的存储方式,正如我们平时所读到的。另一个方面说,Intel处理器(CPUs)和DEC Alphas和至少一些在他们的平台的其他程序都是little-endian的。

作者:AngryFox 分类: Uncategorized January 19th, 2014 暂无评论

1)实现中断响应和中断返回
当CPU收到中断请求后,能根据具体情况决定是否响应中断,如果CPU没有更急、更重要的工作,则在执行完当前指令后响应这一中断请求。CPU中断响应过程如下:首先,将断点处的PC值(即下一条应执行指令的地址)推入堆栈保留下来,这称为保护断点,由硬件自动执行。然后,将有关的寄存器内容和标志位状态推入堆栈保留下来,这称为保护现场,由用户自己编程完成。保护断点和现场后即可执行中断服务程序,执行完毕,CPU由中断服务程序返回主程序,中断返回过程如下:首先恢复原保留寄存器的内容和标志位的状态,这称为恢复现场,由用户编程完成。然后,再加返回指令RETI,RETI指令的功能是恢复PC值,使CPU返回断点,这称为恢复断点。恢复现场和断点后,CPU将继续执行原主程序,中断响应过程到此为止。
2)实现优先权排队
通常,系统中有多个中断源,当有多个中断源同时发出中断请求时,要求计算机能确定哪个中断更紧迫,以便首先响应。为此,计算机给每个中断源规定了优先级别,称为优先权。这样,当多个中断源同时发出中断请求时,优先权高的中断能先被响应,只有优先权高的中断处理结束后才能响应优先权低的中断。计算机按中断源优先权高低逐次响应的过程称优先权排队,这个过程可通过硬件电路来实现,亦可通过软件查询来实现。
3)实现中断嵌套
当CPU响应某一中断时,若有优先权高的中断源发出中断请求,则CPU能中断正在进行的中断服务程序,并保留这个程序的断点(类似于子程序嵌套),响应高级中断,高级中断处理结束以后,再继续进行被中断的中断服务程序,这个过程称为中断嵌套。如果发出新的中断请求的中断源的优先权级别与正在处理的中断源同级或更低时,CPU不会响应这个中断请求,直至正在处理的中断服务程序执行完以后才能去处理新的中断请求。

任何一个CPU,都有处理中断的能力。中断的意思是,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息。
根据中断信息的来源,中断分为内中断和外中断两种。
中断向量表是保存中断处理程序入口地址的列表。
中断过程指的是在找到中断向量后,CPU的硬件自动完成设置CS和IP的过程。
当CPU接收到中断信息后,整个的过程如下:
CPU接收中断信息
根据中断类型码在中断向量表中找相应的中断向量
引发中断过程——CS:IP指向中断处理程序的入口
开始执行中断处理程序
中断处理程序一般需要以下几个步骤:
保存用到的寄存器
处理中断
恢复用到的寄存器
用iret指令返回
iret指令的功能用汇编语法描述为:
POP IP
POP CS
POPF

作者:AngryFox 分类: Uncategorized January 18th, 2014 暂无评论

Simple Scalable Streaming System、Storm、StreamBase、HStreaming、Esper & NEsper、Kafka、Scribe、Flume

http://blog.csdn.net/zmazon/article/details/8618775

文档:http://www.imagemagick.org/RMagick/doc/

https://github.com/alcuadrado/pija/blob/master/README.md

https://github.com/FreebieStock/PHP-Image-Pornographic-Content-Detection

对于这种图像搜索的算法,一般是三个步骤:

1. 将目标图片进行特征提取,描述图像的算法很多,用的比较多的是:SIFT描述子,指纹算法函数,bundling features算法,hash function(散列函数)等。也可以根据不同的图像,设计不同的算法,比如图像局部N阶矩的方法提取图像特征。
2. 将图像特征信息进行编码,并将海量图像编码做查找表。对于目标图像,可以对分辨率较大的图像进行降采样,减少运算量后在进行图像特征提取和编码处理。
3. 相似度匹配运算:利用目标图像的编码值,在图像搜索引擎中的图像数据库进行全局或是局部的相似度计算;根据所需要的鲁棒性,设定阈值,然后将相似度高的图片预保留下来;最后应该还有一步筛选最佳匹配图片,这个应该还是用到特征检测算法。

其中每个步骤都有很多算法研究,围绕数学,统计学,图像编码,信号处理等理论进行研究。

据Neal Krawetz博士的解释,原理非常简单易懂。我们可以用一个快速算法,就达到基本的效果。
这里的关键技术叫做“感知哈希算法”(Perceptual hash algorithm),它的作用是对每张图片生成一个“指纹”(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。
下面是一个最简单的实现:

第一步,缩小尺寸。
将图片缩小到8×8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。
第二步,简化色彩。
将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。
第三步,计算平均值。

计算所有64个像素的灰度平均值。
第四步,比较像素的灰度。
将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
第五步,计算哈希值。
将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。
得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算“汉明距离”(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。
具体的代码实现,可以参见Wote用python语言写的imgHash.py。代码很短,只有53行。使用的时候,第一个参数是基准图片,第二个参数是用来比较的其他图片所在的目录,返回结果是两张图片之间不相同的数据位数量(汉明距离)。
这种算法的优点是简单快速,不受图片大小缩放的影响,缺点是图片的内容不能变更。如果在图片上加几个文字,它就认不出来了。所以,它的最佳用途是根据缩略图,找出原图。
实际应用中,往往采用更强大的pHash算法和SIFT算法,它们能够识别图片的变形。只要变形程度不超过25%,它们就能匹配原图。这些算法虽然更复杂,但是原理与上面的简便算法是一样的,就是先将图片转化成Hash字符串,然后再进行比较。

作者:AngryFox 分类: Uncategorized January 17th, 2014 暂无评论

http://www.cellphp.com/article-read-opensource-15-c-fastcgi-blog-2.0.html

墨霖集团董事长陈默、谷得游戏创始人麦涛、天拓科技CEO黄挺、游爱网络CEO袁雄贵等人在参加一档圆桌会议时,对此进行了解读。
手上有《CPU指令说明》,包里有《芯片组大全》,办公室里放一本《机器代码手册》

yum install libtool.x86_64 LZO.x86_64
mina(发高性能和高可用性的网络应用程序)、NettyGecko在NIO包上提供了高层次的封装,主要支持RPC调用,高性能网络通信。
1. 可插拔的协议涉及;
2. 分组管理和负载均衡(还未搞懂)
3. Failover/retry
4. 重连管理
5. 同步异步

yum install valgrind
使用更大的内存、万兆网卡、组ssd软raid,这些方法已经在使用
什么是内存泄露
内存泄露可以分为两种:
一种是,程序中有指针指向通过malloc或者new申请的内存,但是在程序结束前,一直未收回。如果这种内存一直增加的话,可能导致内存耗尽。不过程序结束后系统会自动回收这些内存。
另一种是,通过malloc或者new申请的内存,但是程序中已经没有指针指向申请的内存。程序一直在执行,泄露的内存会越来越多,可能会耗尽程序的堆内存。

$valgrind –leak-check=full ./test
不同内存泄露情况在valgrind中的表现
对于上述的第一种内存泄露的情况,在valgrind的报告中会表示为“still reachable”。
对于第二种情况的内存泄露,在valgrind的报告中会表示为”Directly lost和Indirectly lost”
另外对于valgrind报告中的“possibly lost”,是因为指针没有指向到申请堆的开始。如,c++的string有内存池的概念。如果程序中使用了string,且非正常退出(如使用ctrl+c快捷键终止程序),会报“possibly lost”
关于使用valgrind检测内存泄露更详尽的文档 http://valgrind.org/docs/manual/mc-manual.html#mc-manual.leaks

mutalbe的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。
在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。

我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种:
静态库:在程序编译时会被链接到目标代码中,程序运行时将不再需要它。
动态库:在程序编译时并不会被链接到目标代码中,而是在程序运行时才被加载的,因此程序运行时还需要动态库存在。
静态库后缀为.a 动态库后缀为.so

参考链接为:

http://hi.baidu.com/coder841112/blog/item/079cff9679b0ce0dd31b7048.html

http://www.cublog.cn/u/21948/showart_161614.html

gcc -static选项可以使得gcc用静态链接,而不用动态链接库
file a.out 可以查看a.out链接形式,采用动态链接还是静态链接
size a.out可以查看a.out的文件中各个段的大小,text、data、bss等
ldd a.out 可以查看a.out所需要的共享库 (ldd参考文献:http://blog.csdn.net/benben85/article/details/4161134)

1、sort
根据指定的方法,以行为单位进行排序,然后输出。
ll | sort -k 5 -n 表示用第五个key进行排序,从1开始计数,-n表示采用数字序,-d表示字典序
ll | sort +4 -5 -n 老式写法,从零开始计数,表示第五个开始,到第六个结束
sort -r -o outfile +1.0 -1.1 example 对于file1和file2文件内容反向排序,结果放在outfile中,利用第2个字段的第一个字符作为排序关键字。
-t表示制定分隔符,默认采用空格为分隔符
2、cut
剪切的作用,以行为单位,指定要剪切的对象,最后将剪切的内容输出。
cut -b 3-10 按照字节剪切,取每行第三个到第五个
-c 按字符取
-f 按照分隔符切割后的field取

命名和编号:
(1) 所有库名以lib开头,gcc在-l指定的文件名前自动插入lib,如libmysqlclient就用-lmysqlclient
(2) .a是静态库(archive),如 libmysqlclient.a
(3) .so是共享库(shared object),如libmysqlclient.so
(4) 编号格式:library_name.major_num.minor_num.patch_num,如libmysqlclient.so.15.0.0
(5) _g和_p: /usr/lib/libform_g.a 中的_g表示这是libform.a的调试库,用locate _g.a会发现很多类似的库,但我用locate _g.so没有发现FC4有此类库;libxxx_p.a中的_p表示这是libxxx.a的性能分析库(profiling),但我用locate _p.a和locate _p.so没有发现FC4有此类路库。
库操作命令:
(1) nm 列出目标文件或二进制文件的所有符号
(2) ar 创建静态库和符号索引
(3) ldd 列出程序正常运行所需要的共享库
建立和使用静态库:
(1) 把代码编译成目标文件,如gcc -c libxxx.c -o libxxx.o
(2) ar: ar -rcs linxxx.a linxxx.o
(3) gcc -static: gcc test.c -o test -static -L. -lxxx
(4) 用file检查静态链接的可执行文件
(5) 用nm检查符号,静态链接没有未定义符号

建立和使用共享库:
(1) gcc -fPIC 产生与位置无关的代码,如gcc -fPIC -g -c libxxx.c -o libxxx.o
(2) gcc -shared和-soname,如gcc -g -shared -Wl,–soname, -libxxx.so -o libxxx.so.1.0.0 libxxx.o (注意-Wl,–soname, -libxxx.so 中间没有空格)
(3) gcc -Wl 把参数传递给链接器ld
(4) gcc -l显式链接C库

http://code.taobao.org/svn/tair/tags/ldb_release_20130809

/usr/local/php/bin/phpize
./configure –with-php-config=/usr/local/php/bin/php-config

分布式环境下一致性的问题而提出的算法。tcpdump来抓包,再用Wireshark来分析。

作者:AngryFox 分类: Uncategorized January 17th, 2014 暂无评论

积分商城,与主站关联,SVN泄露暴露系统敏感信息
源码泄漏漏洞
网站代码打包被下载
配置文件被泄露

12306
在只采用10几台X86服务器实现了以前数十台小型机的余票计算和查询能力,单次查询的最长时间从之前的15秒左右下降到0.2秒以下,缩短了75倍以上。2012年春运的极端高流量并发情况下,支持每秒上万次的并发查询,高峰期间达到2.6万QPS吞吐量,整个系统效率显著提高。

SAP的HANA,和Pivotal的GemFire
sharding,caching,compressing,clustering,cdn

HANA是个share nothing架构的分布式数据库,并且原生支持并行优化。这样的架构使得HANA能够充分利用多核、分布式集群处理大数据问题。这是HANA跟现有主流商业数据库架构上的不同之处,像Oracle、Microsoft SQL Server都不是这样的架构。长远来讲,这将是HANA击败竞争对手的核心能力之一。大数据是行业发展的必然方向,数据本地化和数据级并行是大数据处理技术上的必然选择,而share nothing的分布式架构恰恰就是数据本地化和数据级并行的设计。不过,目前这个阶段,这还不足以成为HANA的杀器,因为share everything架构的数据库也可以处理现在企业面临的数据量。
HANA是个内存数据库。HANA的数据基本上都放在内存里,数据操作都不需要访问磁盘。内存的访问速度跟磁盘完全不是一个数量级的,这使得HANA可以更快的处理数据。当然HANA也有优化,一些不热的数据也会扔到磁盘上去。现在HANA宣传的时候内存数据库这点着墨比较多,但在我看来这不是最大的特色和能力。
HANA同时具有行式数据库和列式数据库引擎。列式数据库本身并没有太多新颖之处,在业内也存在多年。但HANA却颠覆了列式数据库的用途,因为HANA想用列式数据库来处理OLTP的问题。在我看来,这是现阶段HANA的最大杀器,也是HANA在很多场合体现出的高性能的基础。
HANA内置了一些数据建模和数据分析的功能,甚至于把R深度集成了。
SAP推荐在HANA上同时处理OLTP和OLAP的问题,并且也把HANA这么设计。这一点是颠覆过去几十年企业级管理软件领域的思维的。
SAP推荐在HANA上直接处理商业逻辑。这一点是完全反R/3的架构的,因为R/3架构里数据库只处理数据。但是,在大数据时代,要想数据处理的快,商业逻辑就得跟数据在一起。所以这个想法长远来看是对的。

①Tair中会有桶迁移或者namespace清理的操作,废弃的数据并不会立刻清理,依靠后续的compact进程清理。但同时桶又可能被迁移回来,namespace也可能继续使用。leveldb中的SequnceNumber恰好可以标识数据的时间点,所以在做数据清理的时候,记录下当时的SequnceNumber(sequnce_),在做判断的时候,只有小于sequnce_的数据才认为可以被丢弃。
②filenumber_是为了缩小主动compact的范围。
  leveldb自身进行compact的过程中,加入自实现 comparator 的 ShouldDropMaybe()/ShouldDrop() 判断逻辑,会将对应的gc数据清理。但leveldb自身的compact进程并不能保证将所有的数据清理掉,所以添加compact的定时线程,主动触发compact做数据清理。对于清理的bucket或者namespace,根据key的格式,可以构造出需要compact的key-range,但直接使用leveldb提供的CompactRange有以下问题:
  ①如果某个sstable在记录gc之后已经被compact过,所要清理的数据就已经丢弃掉了,并不需要再做compact。
  ②主动触发的compact并不是基于均衡db状态,所以造成的level迁移可能会有反作用。

  对于①、②的问题,做以下策略:
  ①FileNumber全局递增可以用来标识时间点,gc时,记录下当时的FileNumber,主动compact时,只需要选取符合key-range并且FileNumber小于记录的filenumber_的sstable即可,缩小需要compact的sstable范围。
  ②主动触发的compact只选取level-n中的sstable,compact后,也只生成level-n中的sstable,level之间的均衡,仍由内部compact进程负责。

  3)基于上述①②,为leveldb添加CompactRangeSelfLevel()逻辑,实现1) 2)中的策略,主动触发compact以清理数据,整个db的均衡仍由内部的机制保证。
  gc信息会同时记binlog,在server重启时replay。

  2)过期的数据

  因为过期是一个持续的时间状态,如果要完全回收过期的数据,只能对全db做compact,这样做的性能比不合算,所以目前对过期数据不做特别的主动清理,依靠内部以及外部触发的compact进程中回收空间。

  6. 上层cache
  leveldb内部有sstable元信息和block数据的cache,优化读的效率,在leveldb上层再嵌入Tair自带的mdb做KV层面的cache,并添加cache的信息统计。当前统计看到,热点数据的读基本落在mdb中。

  7. 后续的优化

  ①leveldb本身的一些优化(参见leveldb的实现解析)。
  ②优化网络的使用,使用新的网络框架。
  ③ssd使用优化。leveldb内部做的一些细节优化针对于sas盘的IO性能,当前使用的ssd IO能也未充分利用。后续针对提升ssd使用性能做相应的IO优化(dio)。
  ④内存的优化使用。大内存的使用有很大的优化余地,避免swap的使用,pagecache的相应回写策略配置。
  ⑤对不存在数据查找的优化,采用mock value处理或者添加bloomilter。
  ⑥range 以及数据dump功能的实现。

3、Tair编译安装

下载地址:https://github.com/alibaba/tair/

# unzip tair-master.zip
# cd tair-master
# ./bootstrap.sh
# ./configure --prefix=/usr/local/tair --with-boost=/usr/local --with-release=yes
# make -j9 && make install

##configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
    wget http://sourceforge.net/projects/re2c/files/re2c/0.13.5/re2c-0.13.5.tar.gz/download
    tar -zxvf re2c-0.13.5.tar.gz
    cd re2c-0.13.5
    ./configure && make && make install

开机启动要放在/etc/rc.local里
chkconfig crond on
或者在rc.local中配置/etc/init.d/crond start

作者:AngryFox 分类: Uncategorized January 17th, 2014 暂无评论

http://www.cnblogs.com/york-hust/archive/2012/03/28/2420850.html

http://www.cnblogs.com/ychellboy/archive/2009/12/29/1634801.html

http://baike.baidu.com/link?url=Xvh9q3mIb2BpvJ9j6kCbEHE2U1oa_oK_Eji4C3ySVpSpDeCr3cf9XejIbSJoM2sUjvBKsSr48zzix-yckclpN_

Paxos算法一致性算法需要保证:一次选举中只批准一个决议(value),只有被提出(proposed)的决议才能被批准,只有已经被批准的决议才能被学习(即可以执行或保存这个决定的内容)。Paxos算法为了完成这样的选举过程将参与者分为:proposers,acceptors,和 learners。proposers 提出决议,acceptors 批准决议,learners“学习”决议。划分为三类角色后,一致性算法的要求可以更精确的表述为:

1.决议(value)只有在被 proposers 提出后才能批准(未经批准的决议称为“提案(proposal)”);
2.在一次 Paxos 算法的执行实例中,只批准一个 Value;
3.learners 只能获得被批准(chosen)的 Value。
实例(instance):每一个Paxos的实例都将执行Paxos算法的两个阶段过程,并最终选出唯一的决议(value)。

提案(proposal):未经批准的决议称为提案,由于在Paxos算法中,每一个Proposer在一个没有关闭(closed,即还没最终选出决议)的实例中都可以提出自己的提案,因此在一个实例的执行过程中,可能会出现多个提案。而最终只能有一个提案被批准通过,成为该实例的决议(value)。
决议(value):被最终批准通过的提案中的value称为决议,一个Paxos实例只能选出一个决议。决议和实例是一一对应的。

Paxos算法利用Majority机制的投票形式保证2F+1的容错能力,即2F+1个结点的系统最多允许F个结点同时出现故障。使得各角色之间的结构、联系比较松散,加之很弱的先决条件,让paxos算法在实际工程中易于实现。使用单增的实例id来标识决议的方式,使得整个算法的并行性更好(id号大的决议可以先于id号小的决议被批准,不会影响决议序列的顺序)。总得来说paxos算法是很巧妙的,Lamport严谨的证明也保证了算法的正确性。在Basic paxos算法基础上发展而来的fastpaxos只用两次消息传递就能通过一个value,比传统的一致性算法减少了一次消息传递。
Paxos 算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。因此从20世纪80年代起对于一致性算法的研究就没有停止过。节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。Paxos 算法就是一种基于消息传递模型的一致性算法。
不仅只用在分布式系统,凡是多个过程需要达成某种一致性的都可以用到Paxos 算法。一致性方法可以通过共享内存(需要锁)或者消息传递实现,Paxos 算法采用的是后者。下面是Paxos 算法适用的几种情况:一台机器中多个进程/线程达成数据一致;分布式文件系统或者分布式数据库中多客户端并发读写数据;分布式存储中多个副本响应读写请求的一致性。

Paxos算法利用Majority机制的投票形式保证2F+1的容错能力,即2F+1个结点的系统最多允许F个结点同时出现故障。使得各角色之间的结构、联系比较松散,加之很弱的先决条件,让paxos算法在实际工程中易于实现。使用单增的实例id来标识决议的方式,使得整个算法的并行性更好(id号大的决议可以先于id号小的决议被批准,不会影响决议序列的顺序)。总得来说paxos算法是很巧妙的,Lamport严谨的证明也保证了算法的正确性。在Basic paxos算法基础上发展而来的fastpaxos只用两次消息传递就能通过一个value,比传统的一致性算法减少了一次消息传递。

1. database replication, log replication等, 如bdb的数据复制就是使用paxos兼容的算法。Paxos最大的用途就是保持多个节点数据的一致性。
2. naming service, 如大型系统内部通常存在多个接口服务相互调用。
1) 通常的实现是将服务的ip/hostname写死在配置中,当service发生故障时候,通过手工更改配置文件或者修改DNS指向的方法来解决。缺点是可维护性差,内部的单元越多,故障率越大。
2) LVS双机冗余的方式,缺点是所有单元需要双倍的资源投入。
通过Paxos算法来管理所有的naming服务,则可保证high available分配可用的service给client。象ZooKeeper还提供watch功能,即watch的对象发生了改变会自动发notification, 这样所有的client就可以使用一致的,高可用的接口。

3.config配置管理
1) 通常手工修改配置文件的方法,这样容易出错,也需要人工干预才能生效,所以节点的状态无法同时达到一致。
2) 大规模的应用都会实现自己的配置服务,比如用http web服务来实现配置中心化。它的缺点是更新后所有client无法立即得知,各节点加载的顺序无法保证,造成系统中的配置不是同一状态。
4.membership用户角色/access control list, 比如在权限设置中,用户一旦设置某项权限比如由管理员变成普通身份,这时应在所有的服务器上所有远程CDN立即生效,否则就会导致不能接受的后果。
5. 号码分配。通常简单的解决方法是用数据库自增ID, 这导致数据库切分困难,或程序生成GUID, 这通常导致ID过长。更优雅的做法是利用paxos算法在多台replicas之间选择一个作为master, 通过master来分配号码。当master发生故障时,再用paxos选择另外一个master。

作者:AngryFox 分类: Uncategorized January 11th, 2014 暂无评论

http://code.taobao.org/svn/tair/tags/rdb_release_20121009

http://code.taobao.org/p/tair/wiki/guide/

Tair是一个分布式的key/value存储系统,数据往往存储在多个数据节点上。客户端需要决定数据存储的具体节点,然后才能完成具体的操作。
Tair的客户端通过和configserver交互获取这部分信息。configserver会维护一张表,这张表包含hash值与存储其对应数据的节点的对照关系。客户端在启动时,需要先和configserver通信,获取这张对照表。
在获取到对照表后,客户端便可以开始提供服务。客户端会根据请求的key的hash值,查找对照表中负责该数据的数据节点,然后通过和数据节点通信完成用户的请求。
RDB_UNIT_NUM 一个命名空间下的单元划分,默认值是16,决定了并发粒度,下边会有介绍;

RDB_AREA_GROUP_NUM 单机存储引擎的命名空间范围,默认值是512,这个值决定了单机上最多可以有多少个命名空间同时存在(命名空间类似于db name,使用中可以映射到项目,比如可以在area 0中保存项目名到命名空间id的映射,后续就可以在特定的项目内查找key-value);

RDB_MAXMEMORY 单机上rdb存储引擎占用内存的上限值,达到上限后将依据maxmemory_policy的不同采取不同的行为;

RDB_MAXMEMORY_POLICY 达到内存上限后进行的操作,可以直接返回错误,也可以进行LRU,可以参考redis的设置;

RDB_MAXMEMORY_SAMPLES 与LRU实现相关的一个配置参数,可以参考redis的配置;

RDB_LIST(/HASH/ZSET/SET)_MAX_SIZE list、hash、sorted set、set数据结构value最大占用空间的大小,默认均是8k(感觉偏小了);

1.配置修改

为了达到配置统一管理的目的,tair rdb去掉了redis自带的配置文件。它将redis所需的配置统一放在tair配置文件的TAIRRDB_SECTION下边。当前保留的配置文件项有:

RDB_UNIT_NUM 一个命名空间下的单元划分,默认值是16,决定了并发粒度,下边会有介绍;

RDB_AREA_GROUP_NUM 单机存储引擎的命名空间范围,默认值是512,这个值决定了单机上最多可以有多少个命名空间同时存在(命名空间类似于db name,使用中可以映射到项目,比如可以在area 0中保存项目名到命名空间id的映射,后续就可以在特定的项目内查找key-value);

RDB_MAXMEMORY 单机上rdb存储引擎占用内存的上限值,达到上限后将依据maxmemory_policy的不同采取不同的行为;

RDB_MAXMEMORY_POLICY 达到内存上限后进行的操作,可以直接返回错误,也可以进行LRU,可以参考redis的设置;

RDB_MAXMEMORY_SAMPLES 与LRU实现相关的一个配置参数,可以参考redis的配置;

RDB_LIST(/HASH/ZSET/SET)_MAX_SIZE list、hash、sorted set、set数据结构value最大占用空间的大小,默认均是8k(感觉偏小了);

/root/tair_bin/sbin/tair_server -f /root/tair_bin/etc/dataserver.conf

/root/tair_bin/sbin/tair_cfg_svr -f /root/tair_bin/etc/configserver.conf
cat /usr/share/aclocal/libtool.m4 >> aclocal.m4
export TBLIB_ROOT=/usr/local/tb/lib
./bootstrap.sh
./configure –with-release=yes

/root/tair_bin/sbin/tairclient -s 127.0.0.1:5198 -g group_1
/root/tair_bin/sbin/tairclient

127.0.0.1
memaslap memcached的压力测试工具
mysqlslap是mysql的压力测试工具
socktop是systemtap的工具
tcpstat,nmon,mysql sandbox

rethinkdb设计思想:
1)B树会产生大量的随机写操作,对闪存寿命影响较大
2)闪存具有较好的随机读性能,所以B树和cluster index变的不再重要
3)rethinkdb采用append-only方式管理数据和索引,消除闪存上的随机写操作

作者:AngryFox 分类: Uncategorized January 11th, 2014 暂无评论

唯品会、梦芭莎、钱库、QQ网购 酷有拿货网 走秀网、慧聪网

StreamModule

设计用于简化编写分布式程序的库。尝试着使得编写处理异步行为的程序更容易,而不是用同步的外壳包起异步的本质。

SimpleSocket

这个类库让编写基于socket的客户/服务器程序更加容易。

A Stream Socket API for C++
5个项目分别是tfs、tair、webx、OceanBase、athrun。

/dev/shm
首先可以看出来/dev/shm是一个设备文件, 可以把/dev/shm看作是系统内存的入口, 可以把它看做是一块物理存储设备,
一个tmp filesystem, 你可以通过这个设备向内存中读写文件, 以加快某些I/O高的操作,比如对一个大型文件频繁的open, write, read,
据说oracle就利用了/dev/shm(shitou没用过oracle), 可以通过mount命令列出当前的/dev/shm的挂载的文件系统,
Linux默认(CentOS)/dev/shm分区的大小是系统物理内存的50%, 可通过ls /dev/shm查看下面是否有文件, 如果没有就说明当前系统并没有使用该设备.

swap
而swap是Linux的虚拟内存, 即在硬盘上开辟空间当内存不够时充当内存使用, 因此可以理解为当/dev/shm空间不够时可以占用swap的空间

max_fails和fail_timeout —— 这俩是关联的,如果某台服务器在fail_timeout时间内出现了max_fails次连接失败,那么nginx就会认为那个服务器已经挂掉,从而在 fail_timeout时间内不再去查询它,fail_timeout的默认值是10s,max_fails的默认值是1
程序执行时 间+proxy_read_timeout 时间
(1)proxy_next_upstream参数很有用,他可以避免很多 错误
(2)max_fails 参数在繁忙的大型系统中建议设置为3,如果没有几个后端服务器的话保持默认即可。
(3)proxy_read_timeout要根据自身程序而定,不要过大,也不 要太小。如果是php程序,请参照php.ini中的max_execution_time选项值。

当缓存的服务器数量增加或者本身就需要多机房容灾的时候,数据在多机房情况下如何分配,就成了一个问题.会存在跨机房调用的情况,扩机房有啥问题?不同机房的调用网络延迟会比较大。但是一般机房之间的调用是很快的。

​ ​机器分布在单个机房,单份数据
​ ​优点貌似只有方便管理了,物理机器就在一个机房,如果应用机器在多个机器,那就有可能存在跨机房调用了。如果这个放机器的机房出现问题,那机房本身是没有办法容灾的。
​ ​机器分布多个机房,一份数据,对外部而言,就是一个集群
​ ​这种的分布,机器可能对等的分布在多个机房,存储一份数据,虽然物理的部署上是分开的,但是在逻辑上,外部就是认为他是一个集群,如果应用系统也同样分布在多个机房,那就会存在跨机房调用的情况,扩机房有啥问题?不同机房的调用网络延迟会比较大。但是一般机房之间的调用是很快的。这样部署非常适合缓存类的数据,且对于跨机房调用没有那么敏感的情况下。这种情况下,如果一个机房down机了,那这个机器对应的数据会丢失,但是问题不大,因为是缓存数据,可以继续从持久化的系统里面去加载进来。由于是单份数据,也就没有一致性的问题了。
​ ​机器分布在多个机房,一个机房一份数据,对外部而言,每个机房就相当于一个独立的集群
​ ​这种分布,有个最大的好处,就是应用服务器和缓存机器如果在同一个机房,那网络延迟会很小的,机房的调用策略可以配置,就是例如应用服务器所在的机房仅仅能够调用这个机房的缓存机器。但是由于各个机房的数据时独立的,也就是独立集群,数据一致性存在问题,如果应用系统更新数据,是需要同步更新到各个集群的,这个时候,各个独立集群数据一致如何保证呢?目前已知的解决办法是增加一个独立的集群(暂且叫做A-Server)去做这个事情,更新的请求发送到这里,这个集群负责同步数据到各个数据集群,从而来保证一致性。
​ ​两个机房,互为主备,两份数据,经典的主备模式
​ ​主备模式是大家常常见到得了,正常情况下主集群来提供服务,主集群搞一个异步的线程来同步数据到备集群,当主集群挂掉的情况下,应用系统自动切换请求道备集群。这种是能够保证数据一致性的,目前很多DB也是采用这样。最常见的就是mysql的master-slaver模式,如果读写请求的比例差距很大的事情,例如读请求很大,可以增加多台slaver来挡一些读的请求。这种模式下,数据的安全性会比较高。
​ ​机器分布在多个机房,多份数据,对外部而言,整体就是一个集群
​ ​一个集群内的数据是一份,但是多个集群就多份数据,整体对外部就是一个集群,而非一个一个的独立集群,这样有个好处就是可以让应用服务器选择本地机房优先的策略来做事情。
​ ​当然在实际的处理中,可能还有,如何选择呢?根据业务场景去选择,这年头还是场景为王的年代啊,不能生搬硬套。

Pre-Sharding方法是将每一个台物理机上,运行多个不同断口的Redis实例,假如有三个物理机,每个物理机运行三个Redis实际,那么我们的分片列表中实际有9个Redis实例
客户端通过虚拟IP访问主库的物理IP,当主库宕机时,切换到从库的物理IP。只是事后修复主库时,应该将之前的从库改为主库(使用命令slaveof no one),主库变为其从库(使命令slaveof IP PORT),这样才能保证修复期间新增数据的一致性。

1.Version支持:Tair中的每个数据都包含版本号,版本号在每次更新后都会递增。这个特性有助于防止由于数据的并发更新导致的问题。
注:对于版本号的支持,每个数据都包含版本号是不是有必要,毕竟大部分数据更新是不需要的,增加了存储!其实tair这样是变相的想实现事物操作,保证数据更新成功。在redis里面采用的是乐观锁的实现,通过watch key,当多线程操作时,如果在watch key以后其它线程优先操作,会执行失败。对于版本号引入,tair应该有它使用场景的考虑,我们的项目中相关数据有自定义Version来保证数据的一致性。
2.原子计数器:Tair从服务器端支持原子的计数器操作,这使得Tair成为一个简单易用的分布式计数器。
3.Item支持:Tair还支持将value视为一个item数组,对value中的部分item进行操作。比如有个key的value为[1,2,3,4,5],我们可以只获取前两个item,返回[1,2],也可以删除第一个item,还支持将数据删除,并返回被删除的数据,通过这个接口可以实现一个原子的分布式FIFO的队列。
注:对于原子计数器,以及item的支持,都实现了原子操作,这些在实际使用场景中很有作用吧。淘宝在实现这些功能时应该是考虑到项目中的应用场景了。对于其实现方式(在做分布式处理时,这些数据映射到同一结点,相关key增加通过版本号应该就可以很好的实现了