2013-1

0 条评论
31 Jan 2013

Mint 14 x86_64安装wine rtx 2011

刚重装了系统,换到了Mint 14。 之前一直是装虚拟机xp跑rtx的,可是很不方便,内存也不够用,就考虑装wine rtx。

sudo add-apt-repository ppa:ubuntu-wine/ppa
sudo apt-get update
sudo apt-get install wine winetricks
winetricks msxml3 gdiplus riched20 riched30 vcrun6 vcrun2005sp1 vcrun6sp6 vb6run
wine rtxclient2011formal.exe

winetricks过程中可能会让手动去下载包, 照做即可。可能会有一些i386 lib找不到的报错,无视。
安装rtx最后会报一个注册错误,直接跳过。
第一次打开的时候 登录成功, 但是紧接着就卡死了。。。。。。
然后我安装了ia32-libs, 并把环境设置为win7, 然后就神奇地搞定了。

sudo apt-get ia32-libs
winetricks -q win7

无图无真相

会有方块,别人看你的字是横着的,稍微调整一下设置



理论上也同样适用于Ubuntu 12.10

0 条评论
16 Jan 2013

shell拾遗

最近在做分析统计日志的活,又把各种linux下工具拾起来了. 这个做个备忘. (本文持续更新中...)


多进程并行执行的时候将结果重定向到不同文件


ls /home/ | xargs -n1 -P 10 sh -c "echo %0 >> /tmp/\$$.tmp;"

命令标准输出直接赋值到变量


YESTERDAY=$(date -I -d'1 day ago')
echo "---------------------------------"
echo $YESTERDAY
4 条评论
06 Jan 2013

基于Redis的Feed推送系统(四) - 零零碎碎

扩展性/性能/高可用


gearman大概每秒可以接收4k个任务, 单台的能力都是足够了,配置成LVS backup-backup模式切换. 任务通过gearman的扩展写入mysql持久化, 后端的mysql也是Master-Master+LVS切换, 杜绝单点.

aggregator的性能可以通过单组多slave和多组分布+2次mapreduce扩展

distributor的性能可以通过增加worker机和inbox的redis实例提高. 

个人feed的redis需要持久化, 每个节点都有3台: 主->备->持久, 通过LVS切换, 主和备都是纯内存, 持久机不参与工作,只负责写aof.

inbox缓存的redis全部都是纯内存, 可以有多台互相作为备机.


worker管理/健康检查


一开始是用pcntl接管了kill信号, 保证不会在任务进行中被kill掉, 不过strace发现有很多system call比较浪费, 于是改成从数据库读信号.worker做完一个任务后去数据库更新状态, 然后检查kill信号并记log.

start/stop/restart都统一由Manager脚本控制, 除非挂了, 正常情况下不许直接kill. Manager还带有watch功能, 每分钟检查一次所有进程的状态.

Monitor脚本循环跑一个空任务, 做一个sleep一会新增一个, 检查gearman server的状态.


吐槽


尼马gearman 1.1.4是坑爹的啊!mysql断了不会重连, 编译drizzle怎么也搞不上, 换0.41啥事都没有啊!

尼马php的gearman client是坑爹的啊! addServers两台有一台挂了直接就连不上啊!说好的自动failover呢!

马php的redis扩展是坑爹的啊!没有连接池吃CPU又高, 这是闹那样啊!

虽然php5.3换5.4性能有很大提高, 不过还是准备改写成python的, 毕竟后台worker嘛...

1 条评论
06 Jan 2013

基于Redis的Feed推送系统(三) - 分发器

分发器负责向所有在线的用户推送feed, 即前文中的Distributor.

用户产生一条新feed, 先同步插入自己的inbox, 然后交给Distributor分发给所有粉丝.

这里worker有2层, worker1负责接收任务, 按照每3000个粉丝一组分拆成很多子任务, 交给下一级worker2处理. worker2并行处理完成后汇报给worker1, 同时做一些计时和延误告警的工作. 

worker2负责具体的分发流程, 获取粉丝id->判定online->推送并未读数++. 为了追求速度, online是一次性批量获取的, 这里还碰到过一个坑, 参见 http://littlexiang.me/php/3.html .

同时worker2也有大小两个池, 初步设定threshold是100w, 超过100w粉丝的任务会交给large pool处理, 避免某些大佬发了照片来不及处理导致任务积压, 影响了大部分普通用户的分发.

关于性能, 模拟了100w粉丝全体offline和online的情况. 100个worker+2个redis在普通pc机上的分别是1~2s和10~11s.这里扯一个别的问题, 之前测试1个redis的时候, 分发速度是6~7w/s, 分布到2个redis之后居然还是6~7w/s, 最后发现是计算分布写的太罗嗦了, 后来把floor(crc32(id) % 360 / (360 / N))改成crc32(id) & (N-1), 达到了10w+/s, 缺点就是shard数量只能是2^n. 每次扩容必须翻倍, 不过不一定得加物理机, 直接多开一组redis实例就可以了, 因为是全缓存, 完全不用aof和rdb, 一台物理机上开个4个总是可以的.

关于inbox的分布和扩容, 直接添加配置就可以了. 因为online标志和inbox在一起, 所以不需要人工干预迁移, 失效的部分会在下一次用户操作时自动rebuild.

2 条评论
06 Jan 2013

基于Redis的Feed推送系统(二) - 动态聚合器

动态聚合的部分全部基于redis的sorted set, 采用mapreduce计算. 这就是前文中的Aggregator, 主要用于初始化和rebuild.

每个用户都有个人feed的队列, 用户得到的动态就是把所有关注者的feed队列内容聚合起来. 这里采用了mapreduce的计算方式, 先取出每个人的Top 20, 得到N个关注者的20xN条feed, 再进行排序得到最终的Top 20.

对性能做测试的时候, 按照关注上限3000人, 每人队列10000条做了模拟. 循环取3000次15s, 改用pipeline后0.5s, 最后变态地使用了邪恶的eval, 用lua脚本一次性在服务端做完再返回, 结果是0.2s.

    
do
    local ret = {}
    local t = loadstring('return ' .. ARGV[1])()
    for k,v in pairs(t) do
        local key = 'u:' .. v .. ':photos'
        local tmp = redis.call('ZREVRANGEBYSCORE', key, '(' .. ARGV[2], '-inf', 'WITHSCORES', 'LIMIT', '0', ARGV[3])
        table.insert(ret, tmp)
    end
    return ret
end

悲催的是redis的单线程的, 所以这个操作的并发性能很差. 根据redis文档描述 Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. 耗时主要取决于每页的feed条数和关注的人数.

当然可以通过多个read slave来提高并发, 也可以将个人feed队列分布存储在多个redis中, 通过二次mapreduce并行计算.


需要翻页时提供上一页最后一条的score, 取小于score的20条, 才可以保证mapreduce翻页结果正确. 实际中简单地使用了精度到毫秒的时间戳作为score.



intval((microtime(true) - $epoch_ts) * 1000)