• 2021-08-22

    Mac 看图软件 Tovi 免费下载

    Views: 534 | No Comments

    我开发的 Mac 看图软件 Tovi, 支持播放 GIF 动画, 以及用箭头按键浏览上一张下一张. 支持缩放, 旋转, 导出成 mp4 视频等等. Tovi 曾经作为收费软件在苹果 App Store 上售卖, 现在, Tovi 已经免费了.

    下载地址: http://tovi.ideawu.com/

    Continue reading »

    Posted by ideawu at 2021-08-22 10:53:00
  • 2021-08-21

    生产者消费者模式的系统性能分析方法

    Views: 744 | No Comments

    前一篇文章介绍了生产者消费者编程模式, 一种非常流行且强大的编程模式. 本文将分析采用这种模式的系统的性能分析方法, 以做性能优化.

    系统性能分析主要关注这几个指标:

    • qps/rps(queries per second, requests per second) - 每秒处理请求数, 也即吞吐量(throughput), 一般也称为处理速度的大小, 通俗也称为性能
    • latency - 单次请求处理的耗时. 一般关注平均值(avg), 最大值(max), 最小值(min), 百分位(percentile), 一般也称为处理速度的快慢, 通俗也称为性能
    • 成功率, 失败率 - 因为网络抖动或者其它原因, 某些请求的处理会成功/失败, 成功/失败请求占的比例, 失败请求不计算在 qps 里

    其中, qps 和 latency 在通俗语义在常常统称为"性能", 这会给科学分析带来歧义, 所以我们要特别注意弄清楚并区分. qps 和 latency 的关系公式为:

    qps = 1 / avg_latency    // 时间单位为秒
    avg_latency = 1 / qps    // 时间单位为秒
    

    Continue reading »

    Posted by ideawu at 2021-08-21 12:04:42
  • 2021-08-15

    生产者消费者编程模式

    Views: 649 | No Comments

    相信很多人都知道"生产者消费者"编程模式, 也使用过这种模式, 但是, 可能只是本能不自觉地使用过, 未必对这种模式有清晰和深刻的理解. 特别是级联生产者消费者模式, 更是强大无比. 很多人可能没有意识到, Golang 语言的核心思想正是生产者消费者模式, 也即 go routine + channel.

    假设有一个功能, 处理某个任务需要进行3个步骤, 那么代码可以这样写:

    func worker(t *Task) {
        step1(t)
        step2(t)
        step3(t)
    }
    
    for t := recv_task(); t != nil {
        worker(t)
    }
    

    这样的代码非常直观, 也是我所推崇的程序设计核心原则之一. 不过, 这段代码毕竟是串行化的, 中间某个步骤会阻塞后面的步骤.

    对于串行化阻塞问题的最直接解决方案就是多线程并发. 例如, 每收到一个任务, 就启动一个线程去处理:

    for t := recv_task(); t != nil {
        go worker() // 启动线程/协程
    }
    

    这种并发模式有一定的缺陷, 一是并发数量不受控制, 二是如果做了并发数量控制, 这样的控制也不高效. 例如限制最多只有 N 个 worker 线程在同时运行, 如果刚好这 N 个线程都被阻塞在某一个步骤时, 那么整个系统就都没有在工作, 是被闲置的.

    Continue reading »

    Posted by ideawu at 2021-08-15 09:42:47
  • 2021-08-11

    Paxos 算法难以理解吗?

    Views: 840 | No Comments

    Paxos 被冠以"晦涩难懂"的恶名, 一方面来源于它自身的定位不清, 边界模糊, 另一方面来源于它并不直接解决工程上广泛的强烈需求. 工程师们需要一个算法(规则, 协议), 用来开发一个分布式多副本系统, 并让多副本对外表现得像一个单一副本的效果(强一致性, 线性一致性, 外部一致性). 坦率地说, Paxos 距离这个需求有十万八千里. 所以, 广大的工程师便认为 Paxos 算法难以理解.

    首先, 我们需要理解 Paxos 的算法的定位. 不幸地是, 在这第一步, 我们就遇到的麻烦! 大多数人接触到 Paxos 都是从 Basic Paxos 的两个步骤(1a, 1b, 2a, 2b)开始的. 人们花费了大量的精力来记忆这当中的操作步骤, 但是, 却看不到为什么要这样做.

    第一个问题也出现了, Paxos 是不是等于 Basic Paxos? Paxos 是不是就等于那两个步骤? 我们还没谈到 Multi Paxos, 另一个极不完善的理论.

    Continue reading »

    Posted by ideawu at 2021-08-11 21:29:19 Tags:
  • 2021-08-07

    程序设计核心原则: 直观

    Views: 883 | No Comments

    好的代码应该是直观的, 简单的. 直观就是"所思就所写", 想的是什么样就要把代码写成什么样子, 不要七拐八绕.

    例如, 在做结构设计和流程设计时, 我们分析出某个功能流程应该这样做:

    先做步骤1, 然后做步骤2.

    什么是程序设计? 程序设计就是流程, 是串行化, 是先后顺序. 所以, 文档设计完毕之后, 必须写下这样的代码:

    step1();
    step2();
    

    Continue reading »

    Posted by ideawu at 2021-08-07 09:41:49
  • 2021-08-07

    Paxos 和 Raft 的结构差异

    Views: 1204 | No Comments

    如果用面向对象的方法来分析 Paxos 和 Raft 的对象层次结构关系, 我们会发现, 两者其实没那么多差异, 或者说, 这种差异我们平时在做面向对象建模和编写代码时经常使用.

    Basic Paxos

    type Entry struct {
    	promised_num int64
    	proposal_num int64
    	proposal_value []byte
    }
    

    Multi Paxos

    type Node struct {
    	entries []struct {
    		promised_num int64
    		proposal_num int64
    		proposal_value []byte
    	}
    }
    

    Raft

    type Node struct {
    	currentTerm int64 // promised_num
    	entries []struct {
    		term  int64   // proposal_num
    		value []byte  // proposal_value
    	}
    }
    

    首先, Basic Paxos 关注的是一条日志(Log Entry), 和 Raft 不是一个层次的东西. Multi Paxos 和 Raft 的结构类似, 本质上都是"日志复制状态机".

    Continue reading »

    Posted by ideawu at 09:09:04 Tags: ,
|<<<123456789>>>| 2/138 Pages, 825 Results.