1. 读文笔记:Kafka 官方设计文档

    2019-10-13 Sun
    By xiayf

    原文:http://kafka.apache.org/documentation/#design

    数据持久化

    不用惧怕文件系统

    磁盘的读写速度,取决于如何读写。对于线性读写方式,操作系统做了充分的优化:提前读 - 预取若干数据块,滞后写 - 将小的逻辑写操作合并成一个大的物理写操作。

    研究表明:顺序读写磁盘(sequential disk access)的速度有些时候比随机访问内存还要快

    现代操作系统激进地尽可能将空闲内存用作磁盘缓存。所有磁盘读写都经过操作系统提供的统一缓存。这个特性没法轻易关闭,除非直接 I/O (direct I/O),因此,如果程序在用户进程中进行数据缓存,缓存的数据通常也是和操作系统页缓存重复的,缓存两遍,没啥意义,也浪费内存。

    而且,Kafka 是构建在 JVM 之上的,了解 Java 内存使用方式的人应该都知道:

    1. 对象的内存开销非常高,通常是实际数据大小的2倍(甚至更多 …
  2. 读文笔记:Photon - Fault-tolerant and Scalable Joining of Continuous Data Streams

    2019-10-10 Thu
    By xiayf

    原文:Photon: Fault-tolerant and Scalable Joining of Continuous Data Streams

    Photon 是谷歌广告系统中用于 join 广告曝光日志流和点击日志流的一套系统。

    数据流 join 为什么没用 flink 这类通用的流式处理框架?

    数据流 join,特别是广告数据流 join,技术上难在哪里?

    任一条流都可能乱序或延迟,广告点击涉及计费的问题,计费不能多算广告主的钱,也要尽可能避免漏计费,降低广告收入损失。


    该系统在谷歌生产环境中每分钟处理百万级的事件,端到端延迟小于 10 秒(注:对于广告实时竞价的广告主而言,这个延迟的长短很重要)。

    广告曝光、点击整体流程为:

    1. 用户搜索某个关键词时,谷歌的服务器会返回广告和搜索结果。广告服务器会将广告 query 和结果数据作为日志发送到多个日志数据中心(multiple logs-datacenters),最终持久化存储在 GFS 上。每次 query …
    标签: 论文 笔记
  3. 读文笔记:日志 - 每个软件工程师都应该了解的实时数据统一抽象

    2019-10-10 Thu
    By xiayf

    原文:The Log: What every software engineer should know about real-time data's unifying abstraction

    一句话概括,这篇文章细说了 Kafka 的本质原理、解决的问题、适用性等。

    Kafka 本质上是提供日志数据流。

    日志是客观世界的事件记录。

    A log is perhaps the simplest possible storage abstraction. It is an append-only, totally-ordered sequence of records ordered by time.

    日志数据的特点是:只增不改,自带时间戳,数据存储的先后顺序即(大致)是实际发生的时间先后顺序。

    数据库可以基于日志来还原历史操作行为 …

    标签: 论文 笔记
  4. 应用MySQL InnoDB全文索引

    问题

    之前涉及的一项工作要求对某些数据做全文索引,并以API向其他内部系统提供搜索查询服务。

    由于需要建全文索引的数据量并不大,且已有的数据都以InnoDB引擎存储,简单起见,我们选择MySQL InnoDB引擎的全文索引特性来实现。MySQL从版本5.6开始支持InnoDB引擎的全文索引,不过“从5.7.6版本开始才提供一种内建的全文索引ngram parser,支持CJK字符集(中文、日文、韩文,CJK有个共同点就是单词不像英语习惯那样根据空格进行分解的,因此传统的内建分词方式无法准确的对类似中文进行分词)”,我们使用的MySQL版本为5.6.28,并且需要建全文索引的数据部分是中文,所以这是个问题。

    方案

    我们先把这项工作按“分治”的思想拆分成几个小问题:

    1. 由于版本5.6.28的MySQL不支持中文的全文索引,那么可以对需要建全文索引的数据进行预处理 - 分词,并以空格为间隔将分词结果拼接成一个字符串。
    2. 但经过第1步仍是不够的 - MySQL的系统变量ft_min_word_lenft_max_word_len分别规定了全文检索被编入索引单词的最小长度和最大长度,默认的最小值为4个字符,默认的最大值取决于使用的MySQL版本。为了不改变这个默认值同时也是兼考虑这个值对于英文的意义,则需要通过编码(urlencodebase64汉字转拼音等)将中文词变长 …
    标签: MySQL 笔记
  5. 关于并发的一个小技巧

    前段时间在参与实现一个新业务系统的Demo。该系统集成了多个已有系统的数据,涉及的数据量较大,但由于人力少,时间短,没法专门做一个数据处理子系统,所以只能写了很多数据处理的脚本。

    a-simple-concurrency-trick

    为了复用一些代码,这些数据处理脚本和业务系统一样都是使用PHP实现。在某些数据上报API写入的数据较快较多时,脚本处理不过来(特别在脚本涉及一些网络请求时),只能搞起并发处理 - 在我们的情况下,最简单的并发方式就是多运行几个脚本实例。

    但一切没那么简单:脚本从数据库中取出未经处理的多行数据,逐行处理数据,并将处理后的数据更新到原来的数据行中,运行多个脚本实例时,为了避免更新冲突,只好加事务,但加事务后就会频繁发生事务回滚,数据处理速度还是上不去。

    那么该怎么办呢?

    参考哈希的思路,我对脚本做了一点调整,下面举例说明:

    • 假设对同一脚本运行5个实例,为每个实例进程分配一个ID,依次为:0、1、2、3、4
    • 对脚本实例获取数据的SQL,增加选择条件:MOD(id, 5)=SID(SID为当前脚本实例的ID) - 即使用数据行的id对实例数取模,如果结果等于实例的ID,则取出来 …
    标签: 笔记 SQL
  6. 关于API访问频率限制的一个问题

    工作中涉及一些对外开放的无需特殊权限的API,用户会因为某些需求而通过程序来频繁访问这些API,导致系统的负载陡增,可能影响系统其它功能的正常使用。虽然做了一些优化让这种API尽可能地轻量,但仍然不够,因此需要进行访问频率的限制。

    由于这样的API并不多,所以我们并没有在Nginx这样的反向代理接入层中实现频率限制,而是API自己去实现,而且实现方案比较粗糙 - 基于Memcached的缓存自动过期特性。

    方案的PHP示例实现如下所示:

    // 每个IP一分钟10次
    $limit = 10;
    
    $cache = new Memcached();
    $cache->addServer('127.0.0.1', 11211);
    
    $key = __FUNCTION__.$_SERVER['REMOTE_ADDR'];
    $requestNum = $cache->get($key);
    
    if ($requestNum !== FALSE && $requestNum > 10) {
        echo json_encode(array(
            'code' => 403,
            'message' => '请求太频繁,请一分钟后再试',
        ));
        return;
    }
    
    $cache->add …
    标签: Nginx 笔记 工作
  7. 为什么我要送掉纸质书?

    小时候,不知为何喜欢读书,而又没钱买,所以在家都是翻两个哥哥的课本 - 语文、历史、地理等,都翻个遍。更有甚者,竟然还从邻居家偷偷地拿了本书回来,这应该算是我品行上的污点,这事在此说起,也是第一次。

    因为书少,所以至今还记得爸爸第一次送给我的书 - 《一个变两个》 - 连书里的情节都没忘过。

    读初中时,因为读书,还和好朋友闹过一点不愉快:朋友买了一些好书,我想借来看,他不肯,我就每天比大家早起一些,偷偷从他抽屉里拿来看几页,在他到教室之前再放回去,后来“事发”,。。。当然这一切都已过去,朋友还是朋友。

    高中后,开始有一些零花钱/饭钱,从其中挤出部分钱来买书成了我的一个习惯,书也由此越来越多。

    其实我根本看不了那么多书,最终累积了大量的书没认真读过。有时觉得可惜了,就会为读书而读书,精神为读书所累。

    这些年,几次搬家 - 从本科学校到研究生学校、读研期间换宿舍、毕业工作 - 每次最多最重的都是书,“书生搬家 - 尽是书!”。

    工作后租的房子没那么宽敞,导致到处塞的都是书 …

    标签: 笔记 生活 感悟
  8. Base64编码原理与应用

    2015年,我们在青云平台上实现了“百度云观测”应用。青云应用本质上是一个iframe,在向iframe服务方发送的请求中会携带一些数据,青云平台会使用Base64 URL对这些数据进行编码,其提供的编码解码算法示例如下:

    // php版本
    function base64_URL_encode($data) {
      return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
    function base64_URL_decode($data) {
      return base64_decode(str_pad(strtr($data, '-_', '+/'), 
                                strlen($data) % 4, '=', STR_PAD_RIGHT));
    }
    

    可以看出,Base64 URL 是标准Base64编码的一个变种,分别用 -_ 替换标准Base64编码结果中的 +/ ,并删除结果最后的 =

    在实现 “百度云观测” 青云应用时,我在想:

    • 为什么要使用Base64编码?
    • Base64编码算法是什么样的?

    本文是围绕这两个问题思考和实践的结果。

    我认为 …

    标签: 笔记 编码

Page 1 / 6