留言板

February 22nd, 2024 Leave a comment Go to comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 留言板

各位兄弟姐妹们,欢迎各种意见和建议,一起学习提高!

Post Footer automatically generated by wp-posturl plugin for wordpress.

  1. February 28th, 2013 at 08:55 | #1

    Thanks for your data……

    [Reply]

  2. 小书童
    March 2nd, 2013 at 09:44 | #2

    霸爷,我想了解erlang虚拟机本身的实现,已经对各种数据类型的处理,代码应该从哪里开始入手,求指教

    [Reply]

    Yu Feng Reply:

    先问下打算花多少时间?

    [Reply]

    小书童 Reply:

    我不需要理解整个虚拟机的细节,计划一个月时间来对整体思路有个把握,但没找到太多资料。
    已经开始从bif的实现入手,希望霸爷推荐后面的阅读顺序和可参考资料。

    [Reply]

    Yu Feng Reply:

    那就从现有bif的实现入手,不过时间少还是比较麻烦的。

  3. 小龙
    March 5th, 2013 at 19:32 | #3

    褚霸哥, 我想请教一个问题.
    需求:
    我想做一个介于应用与数据库之间的一个中间件(有点类似阿里巴巴Cobar吧, 但是暂时不需要sharding), 功能为能实现后端数据库的主从切换,在切换过程中不至于使得应用程序连接数据库失败,或者抛出异常等不友好的操作(比如说就好象延缓了SQL语句的执行),从而使得主从切换完成后, 正常执行这些语句, 对应用而言这些操作都是透明。

    请问,您好什么好的思路么, 或者有开源软件能做到这类功能的,我想研究下….

    [Reply]

    Yu Feng Reply:

    mysql-proxy可以做这个事情,或者我们的参考我们的UMP: http://mysql.taobao.org

    [Reply]

    小龙 Reply:

    依我之见..后端mysql做主从切换的时候, 最多只能保持mysql-proxy与app之间的连接不断,
    然而在这段期间如果APP不断的向数据库插入信息, 这些插入语句不都会失败么。还是无法解决
    这个问题。

    [Reply]

    Yu Feng Reply:

    是没法100%保证,但是主从切换的概念很小

    小龙 Reply:

    啊,没法子解决了啊?那有没有办法让这个异常对用户更友好一些呢? 我的主从切换就是用zookeeper去做监听…一但主挂了,就让从变成主。

  4. 小龙
    March 13th, 2013 at 14:30 | #4

    请问你们的rds_proxy用于生产环境了么, rds_proxy开源么?

    [Reply]

    Yu Feng Reply:

    线上用了1年多了,目前还没开源。

    [Reply]

  5. mosquito
    March 20th, 2013 at 10:34 | #5

    你好,我想问一下怎么用fio来对硬盘做压力测试,看看硬盘有没有问题,要注意哪些参数?

    [Reply]

    Yu Feng Reply:

    看硬盘有没有问题? 你想测试什么问题?

    [Reply]

    mosquito Reply:

    哦,不好意思没说清楚,都是新的硬盘,看看在fio做压力测试后会不会出现问题。
    不知到要用到fio的哪些参数呢?

    [Reply]

    Yu Feng Reply:

    首先还是你要想清楚业务上要测试什么,比如了解新硬盘的那些特性,然后再翻译成fio脚本。

    mosquito Reply:

    硬盘有好多种,还有SSD . 大小也不确定 一般都用到 1T-4T 的SAS或者SATA.
    不过一种服务器上就用同一种硬盘,最少2个最多70个。请问要了解硬盘哪些特性然后怎么再进一步确定fio的脚本呢?谢谢。

  6. lili
    March 20th, 2013 at 13:02 | #6

    你好:
    看了你很多的blog都收益很大。 今天遇到一个问题想请教你下。
    我再用erlang 和我们的server通讯。 应用层协议头是 Len:16bit CMD:16: Body…
    Len 标示整个协议包的长度。包括Len+CMD+Body。 但是erlang的{packet, 2}
    的设置包头len是只标示Body的产度。 不包含自己Len,2字节的长度。
    所以没有办法和我们的server通信。 但是我有不行使用{packet, 0} 这样要自己分包。
    所以请问你:有没有办法使得Erlang在设置packe的Len把自己本身的长度(2字节)也包含进去。 谢谢。

    [Reply]

    Yu Feng Reply:

    hack代码,加个新的选项,能处理这种情况。自己分效率很低

    [Reply]

  7. ThinkingQuest
    April 13th, 2013 at 13:22 | #7

    正在CMUG现场瞻仰霸爷的风采。

    [Reply]

  8. wang
    April 19th, 2013 at 15:38 | #8

    想请教个问题,假设一个文件有10g大,其中有用的数据有5g左右,这5g分散成不同的块,现在已经知道每块的起始偏移和长度,我copy这个文件时,每次都是先将文件指针移到相应的位置,在拷贝,但是发现这样并不比原来快,想问下您,这中场景下,瓶颈一般会出在哪里?(我怀疑是在fseek?但不是很确定)谢谢了

    [Reply]

    Yu Feng Reply:

    ”copy这个文件“ 什么概念? 之前是如何拷贝的,没听明白你的意图和问题在哪里?

    [Reply]

    wang Reply:

    就是对一个虚拟机的磁盘镜像,通过分析得出这个虚拟磁盘里哪些地方占用了,哪些地方空闲,然后只
    拷贝那些使用的,没有用就seek直接跳过,我就是和 cp命令比较的,不知道为什么反而更慢了。
    ps:回复的好快

    [Reply]

    Yu Feng Reply:

    这样当然慢了,因为普通硬盘最怕移动磁道了,一个磁道移动要10个ms左右,你比如说N个seek,那么占用的时间是N*10ms. 普通磁盘的顺序访问吞吐量是150M左右,假设你移动5次,这个时间用来读取文件的话,可以读取7.5M数据了。顺序访问操作系统和设备都会做预读,这个也是会提高速度的。

    wang Reply:

    有用数据的那些区间也是按顺序的,但因为我是记录每个区间的相对于整个磁盘的绝对的起始位置和长度,
    所以我每次移动文件指针时都是相对于文件的起始位置做移动,那要是这样的话,磁盘的磁头是每次都得从上次写完的位置绕一圈移动下一个位置吗?是这个原因吗?

    Yu Feng Reply:

    顺序移动也是移动呀,磁头移动+精确定位的时间加起来花很多时间的。

    wang Reply:

    非常感谢!解决了困惑我好几天的问题

  9. X
    April 28th, 2013 at 18:06 | #9

    我非常喜欢您的博客,有个问题想请教一下:是个关于进程PID传递的问题
    先写一个测试的文件
    %——–test file start———
    -module(test).
    -compile(export_all).

    test() ->
    [{_, Pid}] = ets:lookup(lv, pid),
    Pid ! “from test()”.

    test(Pid) ->
    Pid ! “from test(Pid)”.
    %——–test file end ——–
    现在测试如下:
    %% 新建lv的table,添加shell的PID
    1> ets:new(lv, [named_table]).
    lv
    2> ets:insert(lv, {pid, self()}).
    true
    3> c(test).
    {ok,test}
    %% 第一类测试 不使用子进程调用
    %% 测试一 :shell接收到了消息
    4> test:test().
    “from test()”
    5> flush().
    Shell got “from test()”
    ok
    %% 测试二 :shell接收到了消息
    6> test:test(self()).
    “from test(Pid)”
    7> flush().
    Shell got “from test(Pid)”
    ok
    %% 测试三 :访问ETS里面的PID,同样可以发送消息
    8> spawn(fun() -> test:test() end).

    9> flush().
    Shell got “from test()”
    ok
    %% 测试四 :这个是疑问所在?为何传递PID在子进程里面无效
    10> spawn(fun() -> test:test(self()) end).

    11> flush().
    ok
    12>

    我的疑问是:
    1. 测试四使用进程间传递PID无效,而测试二直接函数调用有效
    2. 测试三访问ETS储存的PID有效,测试四进程间传递的PID无效,难道储存在ETS里面的self()和传递的self()不同么?估计不是的,但不知道如何解释这个现象。

    [Reply]

    X Reply:

    修改了测试文件,添加了输出PID的功能,发现了问题的所在:
    spawn(fun() -> test:test(self()) end).
    这个self()其实不是shell的self()而是一个新的PID
    但还是不太理解spawn(fun() -> test:test(self()) end).的调用过程,如果理解了调用过程,估计就好理解为何self()的值不一样了。
    希望可以解释一下,谢谢了!

    [Reply]

  10. April 28th, 2013 at 18:12 | #10

    spawn(fun() -> test:test(self()) end). 这段代码的self()是在fun里面执行的对吧,而fun是在新进程里面运行,所以self()是新进程的id, 这就是问题。 同样的函数,不同的上下文,结果不同。 所以说erlang不是纯正的fp语言。 建议少在函数里面用这种函数,靠参数从外面传进去比较好。

    [Reply]

    X Reply:

    谢谢啊,一直在测试,网页没有刷新的,所以reply了自己一下,原来有回答了,真的非常感谢!

    [Reply]

  11. Nobody_Ppc
    May 9th, 2013 at 15:24 | #11

    霸爷,一直关注你的博客,一直关注erlang,目前系统需要做一个POP3邮件接入,正好目前在学习erlang,打算用erlang在做一个pop3服务器,劳烦霸爷推荐下是否有相关的开源系统,谢谢!

    [Reply]

    Yu Feng Reply:

    github上找找,做个pop3协议网关还是小菜一叠的。

    [Reply]

  12. Nobody_Ppc
    May 9th, 2013 at 15:43 | #12

    非常感谢!工作一直用C++,学习erlang也有半年多了,非常想尝试一下将它用到工作中,提高效率,刚好做的也是移动的项目,bingo!

    [Reply]

  13. ckwei
    May 20th, 2013 at 10:08 | #13

    霸爷,你好啊,一直关注你的博客,收获很大。

    最近在写nif的时候,遇到一些小疑问,网上给出的答案不明确,想请教下你。

    我看《Erlang and OTP in action》的时候,里面第12章“用端口和NIF集成外围代码”,12.3.1“初始链入式驱动”时,里面说到链入式驱动代码可能被生成周期相互重叠的多个独立端口并发调用,在运行时所有这些端口共享erlang VM的内存,而且不同端口还可能分属不同的线程,因此驱动代码必须是“可重入的”,也就是不得依赖全局变量和锁

    里面就列举了一些解决方法,例如全局变量避免使用,动态内存分配,需要改为erlang erl_driver中的driver_alloc, driver_free

    我的问题是

    1)nif有没有上面所说的问题?例如在nif中使用的c代码,必须要能够“可重入”,动态内存分配需要改掉,等等
    2)nif使用时,除了小心nif会阻塞erlang VM调用,c代码必须尽快返回外,还有没有什么需要注意的?

    PS:我正在做的项目是一个游戏项目,使用nif来实现SAP算法,里面会维护一些自己的数据结构,可以想象为c代码提供一些操作数据,查询的接口通过nif暴露给erlang

    [Reply]

    Yu Feng Reply:

    nif不能阻塞,而且要重入,所要要求:

    1. 尽量不使用全局变量,除非只读的或者配置用的。
    2. 内存最好用driver的alloc函数
    3. 不能做阻塞操作,需要长时间的操作,用driver提供的异步线程池来解决。

    [Reply]

    ckwei Reply:

    我其实不太明白一点,nif的官方手册上面说,“NIFs are called directly by the same scheduler thread that executed the calling Erlang code. The calling scheduler will thus be blocked from doing any other work until the NIF returns”。也就是说,nif是在由一个线程单独驱动的,这样为什么还要要求nif c代码是可重入的呢?nif都不会以多线程的方式去调用。

    [Reply]

  14. sunface
    May 24th, 2013 at 17:55 | #14

    大神我想请问下,用LUA来做erlang游戏的AI部分,可行性如何?能帮我分析下嘛?

    [Reply]

    Yu Feng Reply:

    lua做这个AI挺好的,lua严格多线程安全,没有锁。

    [Reply]

  15. ericxu
    May 28th, 2013 at 16:29 | #15

    霸爷,平时从你博客学了很多知识,非常感谢!我参照了你systemtap内嵌C语法的文章,写了一段systemtap脚本查询kernel中每个内存node(pg_data_t)中的每个zone的name(/proc/zoneinfo有对应的名字), 代码非常简单(UMA系统):

    struct pglist_data* node;
    7 size_t i = 0;
    8 size_t j = 0;
    9 size_t k = 0;
    10
    11 node = NODE_DATA(0); //UMA system, return &contig_page_data
    12 if (node == NULL) {
    13 _stp_printf(“node is null\n”);
    14 return;
    15 }
    16
    17 for (k = 0; k nr_zones; ++k) {
    18 struct zone* zone = node->node_zones + k;
    19 _stp_printf(“k:%d, zone:%p, name:%s\n”, k, zone, zone->name);
    20 }

    结果 name显示为, 不知道是为何。(我的系统只有一个DMA,一个NORMAL type 2个zone, no highmem)
    —————————————————————————-
    pass 5: starting run.
    k:0, zone:0xc17b5b6ec18a0840, name:
    k:1, zone:0xc177e76cc18a0b80, name:

    事实上这个问题是我想打印node中的node_zonelists而遇到的。 为什么打印不出来呢?

    [Reply]

    ericxu Reply:

    name显示为null, 被编辑器给吃掉了

    [Reply]

    Yu Feng Reply:

    参见vmstat.c:

    /*
    * Output information about zones in @pgdat.
    */
    static int zoneinfo_show(struct seq_file *m, void *arg)
    {
    pg_data_t *pgdat = arg;
    struct zone *zone;
    struct zone *node_zones = pgdat->node_zones;
    unsigned long flags;

    for (zone = node_zones; zone – node_zones < MAX_NR_ZONES; zone++) { int i; if (!populated_zone(zone)) continue; spin_lock_irqsave(&zone->lock, flags);
    seq_printf(m, “Node %d, zone %8s”, pgdat->node_id, zone->name);
    seq_printf(m,
    “\n pages free %lu”
    “\n min %lu”
    “\n low %lu”
    “\n high %lu”
    “\n active %lu”
    “\n inactive %lu”
    “\n scanned %lu (a: %lu i: %lu)”
    “\n spanned %lu”
    “\n present %lu”,
    zone->free_pages,
    zone->pages_min,
    zone->pages_low,
    zone->pages_high,
    zone->nr_active,
    zone->nr_inactive,
    zone->pages_scanned,
    zone->nr_scan_active, zone->nr_scan_inactive,
    zone->spanned_pages,
    zone->present_pages);

    [Reply]

    ericxu Reply:

    谢谢霸爷,这个函数我今天也读过了一下。其实我的问题不是zone->name具体是什么值,而是为什么在systemtap里内嵌代码_stp_printf(“%s\n”, zone->name); 却打印不出来zone->name的字符串值。
    lxr上check了下代码, zone->name是声明成const char*的,很是奇怪。

    另外我在probe begin {

    }

    [Reply]

    ericxu Reply:

    probe begin { printf(“%s\n”, kernel_string(0x12345678)) }, 其中0x12345678是zone->name的地址(用%p打印出来的), stap 运行的时候提示出错了。一直没有想明白。

    ericxu Reply:

    已经找到原因了,今天仔细check了下结果,发现指针都是居然是64位的(%p), 而我的是32位机器。
    将指针修改成%x,name也顺便能打印出来了。估计%p将栈搞乱了,导致zone->name打印不出来了。谢谢霸爷。systemtap真是好东西,看书看半天没看明白。按照你的文章,去打印了一下数据结构中的值,对照/proc目录下的值,慢慢能理解概念了。

    Yu Feng Reply:

    恩,不错,好好用这个工具。

  16. hb12112
    June 3rd, 2013 at 11:57 | #16

    你好,在使用flashcache对KVM windows桌面系统做加速时,系统启动失败。分析是数据一致性问题,在解bug的过程中发现在接收到上层BIO的时候,多个vector中的page全都指向同一个page,这种现象有什么合理的解释么?谢谢!

    [Reply]

    Yu Feng Reply:

    应该不会,这块是最核心的东西,这么久了没发现这个问题。

    [Reply]

    hb12112 Reply:

    有没有可能是KVM导致的?我们在测试linux启动的时候是正常的,而且用一致性工具测试的时候也没有出现这样的问题。

    [Reply]

    hb12112 Reply:

    cnt:0 addr:ffffea0018b48ee0 offset:0 len:4096
    cnt:1 addr:ffffea0018b48f18 offset:0 len:4096
    cnt:2 addr:ffffea0018b48f50 offset:0 len:4096
    cnt:3 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:4 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:5 addr:ffffea0018b48188 offset:0 len:4096
    cnt:6 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:7 addr:ffffea0018b481c0 offset:0 len:4096
    cnt:8 addr:ffffea0018b481f8 offset:0 len:4096
    cnt:9 addr:ffffea0018b48230 offset:0 len:4096
    cnt:10 addr:ffffea0018b48268 offset:0 len:4096
    cnt:11 addr:ffffea0018b482a0 offset:0 len:4096
    cnt:12 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:13 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:14 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:15 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:16 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:17 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:18 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:19 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:20 addr:ffffea0018b482d8 offset:0 len:4096
    cnt:21 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:22 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:23 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:24 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:25 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:26 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:27 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:28 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:29 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:30 addr:ffffea0018b2b200 offset:0 len:4096
    cnt:31 addr:ffffea0018b48310 offset:0 len:4096

    贴在上make_request_fn函数处的打印。从上面可以看到addr:ffffea0018b2b200 这个地址在同一个BIO中重复使用多次。

    这个是在没有加载flashcache的情况下打印出来的。

Comment pages
1 3 4 5 6 7 8 65
  1. No trackbacks yet.