lee的个人空间

    理论指导实践,实践验证理论

    正在浏览 生活 里的文章

    CPyUG本与我无关,鄙人连业余Python开发者也算不上,纯粹是打了个酱油,但这次线下活动依然有些收获

    第一位演讲者来自搜狐,讲述他逛贴吧直播贴而产生的idea——利用python脱水后实现的只看楼主功能,其中很多有语言专业性的东西没听懂,但给每个参会者一个启示:天才的idea都来自我们身边,只要有心将其实现就有可能成为用户真正需要的产品

    第二位同样来自搜狐,分享的主题pvinsight——搜狐内部针对日志访问的统计系统,利用“分时”与“分治” 的思想,定义了一系列有利于运算的数据结构,最终满足海量数据的处理需求。他的演讲内容与我的工作内容有很大共同点,我近期的任务是处理每天80G的日志量,并产生基于位置、用户行为的统计报表,以指导市场决策;基于此会后我找到演讲者,索要了联系方式,虽然他用python,我用java,但可以借鉴方法,毕竟他的方案经过考验。

    第三位演讲者来自天涯社区,分享的是当前非常火热的Nosql,现在探讨技术不沾点海量数据处理、云计算、分布式开发的边,你还真不好意思跟人打招呼。

    先前有看过一篇讲天涯系统架构的贴,不知靠谱不靠谱,贴出来大家鉴定:http://sudone.com/archie/tianya.cn.html ; 今天这位天涯兄弟讲的是利用Memlink缓存系统来应对每天上亿的pv请求,Memlink是一个纯粹的内存存储系统,与memcache有点相似,同样是在client端实现分布式算法(后来仔细一想:一主多从何来客户端分布算法?这位兄弟口误?),但memlink基于key-list存储,读写分离(读写分不同的端口),目前仅支持一主多从,这样设计可以极大的减小并发写带来数据不一致性的几率,但单点写毕竟会有性能瓶颈,达到写上限要scale-out就非常困难了;memlink支持数据dump到disk以及些redo日志实现数据持久化;后来这位仁兄介绍说天涯论坛中间层有基于key-list,key-value多种形式存储的综合体,key-list中存储定长的主键ID-list,然后在批量的从key-value缓存中获取内容,再返回给用户最终数据。总体感觉,这个项目定制化过强,客户端编程要求比较苛刻,可以参考实现方式,但在其他项目的实用性有待考证!

    我觉得还是第四位演讲者最给力,压轴的果然是在最后,我说过我打酱油的,python界牛人我听说过的不会超过两个,在会场偶遇的两位朋友提起压轴演讲者,业内尊称他教主。。哦。有眼不识泰山!曾服役于豆瓣,后来写了个网站,拉到了投资,成立了一个小团队;他分享的开发经验很实际,很受用,Q&A环节就能看出这人的个人魅力,其中讨论的技术细节我不清楚,但就认为这人是牛,有气场!恩。

    以后技术沙龙活动还是得多参加,多学习别人的经验!

    还有个事得提一下,我凭借69这个数字抽中了2等奖,获得了一枚搜狐公仔,多惊喜!!

     

    该算法是参考锁相环时间同步某一论文的改版,本文比原文要通俗易懂,我想拿到那篇论文一般人都不会有继续阅读的欲望。所谓专家就是这样,自己不明白的理论想尽办法把别人弄糊涂。

    时间同步算法在很多场合都会应用上;锁相环时间同步是一种比较好用的算法,不废话,直接进入主题

    处理流程

    1, 客户端向服务端发起请求带上参数T1(当前客户端时间) Tdelay(网络延迟);Tdelay在第一次请求时是个经验预估值,之后的步骤会一步步校准它

    2, 服务器接收到客户端请求,当前服务器时间点为T2

    3, 服务器端处理请求总共花销Tdelta时间,处理完的时间点为T3

    4, 在T3时间点需要预估当前客户端时间T3Est,以及客户端接收到响应的服务器时间点(T4Est)

    5, 客户端在T4接收到服务器端响应,响应包含Tdelta,T3Est,T4Est,此时客户端要计算出Tdelay

    6, 结合第5步计算出的Tdelay,重复第1步;

    根据实践经验,以上步骤循环次数越多,最终客户端同步后的时间与服务器时间越接近(不管循环多少次,该计算方法获得的结果,只能无限逼近服务器端时间),当然也取决于对Tdelay的经验预估,初始Tdelay越接近实际网络延迟,则可以在较少的循环请求次数获得相对准确的同步时间

    公式

    Tdelta:服务器端处理客户端请求所花费的时间

    Tdelay:网络延时

    T3Est:在T3时间点,从服务端预估此时客户端的时间

    T4Est:在T3时间点,预估客户端接收到响应时服务端的时间

    服务端:

    Tdelta=T3-T2(在服务端端计算的已知值)

    T3Est = T1+Tdelay+Tdelta

    T4Est=T3+Tdelay

    客户端:

    Tdelay = T4-T3Est

    从以上等式可以得出

    Tdelay=  (T4-T1-Tdelta)/2  (只与客户端时间有关)

    发送监测消息同步后的时间计算 SyncronizedTime = Client_Current_time – T4 + T4Est

    改进

    在上述计算过程中,我们做了一个假设,即请求网络延时等于响应网络延迟,考虑到无线互联网络带宽限制,两者往往不会相等,有可能还会相差很大,若将Tdelay拆分成reqDelay和ResDelay计算结果将更准确

    QQIP数据库保存了全球的IP及国家地域信息,甚至详细到某所大学、某个网吧名称,也许你开始掰着指头开始计算:一三得三,二四得八,三八妇女节,六一儿童节;根据IP计算规则,IPv4所有IP数为256^4,还需要包含国家地域等信息,实际上QQIP库只用8M就保存下来了。是不是对它的存储格式有些好奇,我们从lumaqq的开源协议可一窥它的存储细节:http://lumaqq.linuxsir.org/article/qqwry_format_detail.html

    本文就主要从整体上来分析QQIP数据库是如何存储的、采用不同存储策略的缘由,最后再分析像ip138.com如何从IP快速定位到地域的。

    QQ IP数据存储规则:按照IP段(起始IP-结束IP)来存储,并非每个IP都记录,起始IP会放置在索引区,紧接着记录结束IP的偏移位置,结束IP会放在记录区;整个IP段都是递增存储的。

    QQIP数据库整体结构如下,橙色区域是文件头,绿色区域是记录区,淡蓝色是索引区

    qqip_structure

    第一种最简单的IP记录形式:

    simpleIP后面直接跟国家记录,0结尾,紧接着地区记录,0结尾

    比如我们要存储以下两个IP段

    1.2.3.4——1.2.255.255 分配给的是北京搜狐的(这只是举例,非真实)

    2.4.5.6——2.4.255.255分配给的是湖南联通的(当然这也是捏造的)

    北京搜狐的16进制表示:b1  b1  be  a9  cb  d1  ba  fc

    湖南联通的16进制表示: ba  fe  c4  cf  c1  aa  cd  a8

    记住QQIP库都是按照little-endian存储的,如有不明白可借助搜索引擎,这里简单说明下:IP1.2.3.4应该按照正常顺序存储的,但按照little-endian就变成4.3.2.1顺序了

    这里为了方便对比:ip用十进制存储,文件头(橙色)、国家地区以及位置偏移量采用16进制,对比就明白QQIP的内部数据存储结构了

    simple_data_structure

    重定向模式1

    第一种模式毕竟对汉字的重复利用率不高,比如分配给北京搜狐的有10个IP段,依旧按第一种方式存储显然就浪费存储空间了,因为北京搜狐这8个字节要重复存储10遍,你可能想到了只存储一次北京搜狐,其他IP段用一个地址指向它就可以了,没错,因此也就有了重定向模式1方式,如下图
    redirect1比如:分配给北京搜狐的IP段有:122.10.1.4——122.10.1.255

    123.10.12.1——123.10.12.255

    redirect2

    见黄色区域,第二条IP之后没有直接存储国家和地区记录,而是先用0×1标识是重定向模式1,之后三个字节即是国家和地区的偏移地址,00000d代表的是当前IP指向的国家和地区记录从第13个字节开始;细心的朋友可能察觉到了,同样是存储两个IP段,该种存储方式明显比最简单的存储方式节省了6个字节;该法适用于给同一个地区分配了多个IP段的情况

    可以想象,给一个国家分配的IP段肯定会比一个地区分配的IP段多的多,拗口??那这么说,整个北京(国家)拥有的IP段肯定会比搜狐(地区)拥有的IP段多,所以第二种重定向模式就派上用场了

    redirect2_2

    这种存储模式主要是为了最大重复利用国家字符串。

    举例:让你来存储北京搜狐:13.1.10.5——13.1.10.255

    北京联通:14.10.144.2——14.10.144.255

    北京联通十六进制表示法可以通过上文推导出来,实在看不出端倪就用java格式化方法String.format(“%4x”,byte);这就不列举最终的存储数据了。

    分析QQIP存储方式

    优点:

    1. 采用二进制存储,比字符串更省空间
    2. 采用三种存储模式,最大利用国家地区信息
    3. 有索引区,并且索引升序存储,方便检索

    不足:

    1. 不方便扩展,如果要新增一个IP端,或者修改一个IP端,整体结果都会变化
    2. 二进制存储不够直观

    接下来就来介绍类似ip138是如何从用户输入的IP快速定位到所属地域的,根据QQIP存储区域,我们用伪码来表示实现过程

    • 用户输入IP
    • 在索引区Binary Search(IP);   //前文以提过,IP都是递增存储的,并且可以直接从文件头定位到索引区。所以二分查找是最快的。
    • 找到位置后,获取IP后三字节,即IP段结束IP的偏移位置
    • 确定是哪种存储(重定向)模式 //ox1 or ox2 or other
    • 根据规则获取国家及地区

    虽然这种方法定位效率很高,但毕竟查找是要花费时间的,可以考虑加入缓存的,先从缓存查找,若找不到再去文件数据库查找,查找到的结果put到缓存。

    这里还介绍一种IP的整形表示法,在做IP地域关联时,相对数据处理更优;

    1.2.3.4整数形式: 1*256^3+2*256^2+3*256^1+4  有没有想到c语言课上做的习题?将一个十进制数拆成个十百千独立的位,这里是逢256进一;整数表示的IP比字符串表示法更方便比较,做统计时会更快捷。

    Google前一段时间发布了免费的DNS解析服务,声称能加快用户浏览体验,并且其Server IP 好记无比8.8.8.8  但是并不是所有用户DNS设置成这个IP就是最快的。

    这个得说下DnS是做什么的:
    dns就是域名解析服务器,通俗点说就是 互联网表示网站地址只能是点4分开的ip数字,但人们对数字的记忆很是不敏感,所以就有了用字符来替代IP数字的方法: 但需要一种服务器来把好记的字符转换成数字代表的IP  这个服务器就是DNS 举个例子: 大家都喜欢上百度,输入的地址是www.baidu.com,然后打开了百度的主页,其实你真正访问的是http://119.75.216.30/

    Google的一位工程师花了他每天工作20%的时间写了一个测试并找到最快的DNS server: 我下载尝试了下并找到了最快的DNS server比google的dns快了270%

    这个工具下载地址: http://code.google.com/p/namebench/
    我下的是win版本的:这个工具会自动搜集你浏览的历史记录,以及tcp输出的数据包为检测标准
    使用非常简单:

    工具使用

    你只需要选择Benchmark Data Source  这里没有IE的,也是因为这个工具支持多操作系统或者因为竞争关系没有将其列入其中; 我常用的是firefox  选择 Mozilla Firefox,其他可以默认 点击Start Benchmark按钮等大概几分钟就能找到最好的DNS Server了

    2

    3

    45

    6

    从上面的图可以看出来按照我现在的网络现状 最快的DNS server是202.106.46.151 比8.8.8.8快了270%
    你要感兴趣,你也可以去找到你最快的适合你的dns server
    最后再将DNS设置成这个IP for win  : 打开网络连接:—->属性  —》选中internet 版本协议4  点击属性  —>出现下图:设置一下就OK了

    78

    在晚上10点多,收到老大发来的信息,以下是原文:

    (i美股讯)北京时间3月23日晚消息,今日,斯凯(MOBI,10.44,+10.13%)宣布与搜狐(SOHU,80.58,+0.54%)在移动广告领域合作,斯凯在MRP平台与搜狐合作开发广告分成模式。受此利好消息的影响,斯凯今日开盘后于本周三大涨21.52%,于11.52美元报收,创下52周以来的新高。

    虽然跟我没太大直接关系,但我们所开发的产品能让合作方股价有如此大之影响,让人振奋!

    目前项目已上线,期待二三期及在运营推广上同样顺风顺水!

    附新闻链接