• MongoDB 那些坑 at 2014年06月25日

    #30 楼 @luikore 原来你说的时这种内嵌式的,但很多需要事务的场景,里面有大量 model,他们是无法满足这种情况的。

  • MongoDB 那些坑 at 2014年06月25日

    #25 楼 @birdfrank #23 楼 @aptx4869 是建了索引的,在_type 上面,我说的是使用了 in 语句无法利用索引;不过我的这个观点估计也是错误的,因为我今天用 explain 分析后,即使继承后用 in 语句也可以 hit 索引,所以为什么查询比较慢,只能从其他地方找原因了。谢谢你们的提醒。

    #27 楼 @luikore 你说的第一种方法,用原子方法搞定,不知道如何具体操作,有实践方案么?我用的估计是你说的第二种方案,用 id 作为 key 来管理事务对象,但是否能利用上你说的 redlock,这个我没有具体研究过。

  • MongoDB 那些坑 at 2014年06月24日

    我们项目组,使用 mongodb 已经 2 年多了,目前的版本是:2.2.1。针对使用中遇到的问题,谈点我自己的感受吧,既然这个帖子基调已定:),所以好处就不用废话了,就谈点注意事项而已。

    1. 一定要合理创建索引,有很多人都被宣传片迷惑,认为 mongo 的读取速度本身就应该很快,所以从 mysql 转过来后,就连创建索引都忘了,当表 (collection) 很大时,不创建索引是非常影响性能的。创建索引很简单,如果你不想使用 shell 那么麻烦,直接在 model 里面声明就是了:index({ xxx: 1 }, { unique: true, background: true });然后运行一个 rake 命令:rake db:mongoid:create_indexes 就 ok 了,这个命令不会重复创建的。
    2. 大表查询时,只返回你想要的列,楼主讲了很多 write 的性能问题,可能是场景不同的原因,我们大量遇到了查询的性能问题;这一点就不用多说了吧,其他关系型数据库也有这种问题。特别是单 collection 字段数据量比较大时,非常容易引起性能问题,在 rails 里面也很简单,查询时加上 only 就是了。比如 User.where(xxx).only(:f1,:f2) 。
    3. 尽量一次返回所有需要的数据,避免 GET_MORE,避免游标操作,当用户进行查询迭代时,mongo 会首先返回一个数据块供你迭代,当你迭代的数据超过这个数据块时,mongoid 发起 GET_MORE 命令移动游标获取下一个数据块,而就是这个移动游标的操作就非常慢,特别是你返回的列比较多的时候,性能非常低。每次返回的数据块的大小是由 batchSize 控制的,可以通过修改它的默认值进行控制。
    4. 尽量避免在 model 里面使用 Array 类型的字段,原因楼主已经说了,不过我们遇到的还是查询的问题,因为你使用了 Array,查询时,你不可避免的会使用 ##in## 操作,in 操作无法利用索引,这个在关系型数据库里面也是存在的,大表操作一定要避免。
    5. 不要在和数据库直接相关的 model 里面使用继承,什么意思呢?就是 modelB < model A ,而他们都是 mongo 里面的 document,为什么不能这样?因为 mongoid 的内部实现其实只会创建一张表就是 documentA, 然后在 documentA 里面用一个 _type 字段来标识 documentB,这样当你查询 modelB 时,内部会生成一个查询到 documentA 的语句,那个查询就是用的 _type in [xxxx] 类似这样的语句,你看又是 in 操作。如果这种情况你是在后期才发现的,你真是回天无术,想死的心都有:)。
    6. 事务,还是事务,mongodb 不支持事务,所以你一定要考虑清楚,权衡利弊。我们有些功能就必须使用事务,没办法,我想到一个非常丑陋的方法,记录每个创建和更新的 model,它的 id 和更新数据,如果一旦有异常,我就撤销更新和创建,真的是非常麻烦。想想看在一个支持事务的关系型数据库里面,这些是非常简单的。
    7. 主从备份还不是很成熟,这一点,估计是我研究的不深入的原因,我仍然认为主从备份不是很成熟,有些时候简直就是提心吊胆,如果有经验的同学在这里,可以多多讨论。

    为了在开发环境下统计耗时的查询,我 monkey 了 Moped 的代码,这样可以很容易的查看哪些比较耗时的查询。代码如下:

    # encoding: utf-8
    module Moped
    
      # Represents a client to a node in a server cluster.
      #
      # @api private
      class Node
    
            if Rails.env == 'development'
    
                @@time_consuming_msg = []
    
                alias_method :log_operations_old, :log_operations
    
                def log_operations(logger, ops, duration_ms)
                    log_operations_old(logger,ops,duration_ms)
                    time = duration_ms.round(2)
                    if time > 30.0  # > 50ms
                        #p '='*100
                        t_s = "%.4fms" % duration_ms
                        @@time_consuming_msg << {msg: "#{ops.first.log_inspect} (#{t_s})", time: time}
                    end
    
                end
    
                def self.print_consuming_time_stat_info(logger)
                    if @@time_consuming_msg.size > 0
                        log = MongoidColoredLogger::LoggerDecorator.new(logger)
                        log.warn "\n"
                        log.warn "\e[33m#{'*'*100}\e[0m"
                        log.warn "\e[31m#{' '*32}Query consuming time -- Top ranking list\e[0m\n"
                        @@time_consuming_msg.sort{|x,y| x[:time] <=> y[:time] }.each do |msg|
                            log.warn msg[:msg]
                        end
                        log.warn "\e[33m#{'*'*100}\e[0m\n"
                        @@time_consuming_msg = []
                    end
                end
    
            end
        end
    
    end
    

    以上如果有问题的地方,还请多多指教。

  • #8 楼 @qifengle 没有大小写跳转,貌似只是针对 topics 做了跳转。具体是代理服务器做的还是在代码里面做的,我也不知道。

  • #1 楼 @blacktulip url 默认大小写确实是敏感的。这种解决方案不错。

    #2 楼 @huacnlee 本来应该是敏感的,你可以访问这个: https://ruby-china.org/Topics/20052; 但为什么 https://ruby-china.org/TOPICS 是正常的,我猜是不是哪里做了设置了。

  • @lgn21st 可以 remote 不?

  • 走好,不送。其实我一直觉得管理员们都太宽松了,楼主显然没去过早期的 JavaEye,也许那边现在还是非常严格,要运营一个好的社区就应该这样。

  • #13 楼 @hayeah 哈哈,最初我也是这么想得,搞得很复杂。到最后,实现其实很简单的,因为我用了 ace editor,它可以记录大部分更改。接下来就是搭积木而已。不过,现在 node 的基础设施已经很完善了,包管理,程序构建,发布,Js, Css 打包压缩,这些 rails 社区有的,在 node 世界里面都可以找到相应的实现。除了各种 callback 很烦之外,构建小程序 node 非常优势,关键是社区的优势 像 Yeoman 的各种构建器,Grunt 的各种构建任务,大大加速了 node 从零构建 app 的速度。相对来说,rails 现在都趋于复杂化。

  • #9 楼 @hayeah 同步用的 socket.io 啊,但是视频那个地方还不是很好,准备修改完后放到 github 上开源。但最近又很忙,都很久没搞 nodeJS 了。等忙过这一阵子,开源出来,共同进步。

  • 学 node 的时候,做的 demo : http://showthecode.tk/ ; 可以多人同步 code,同步视频。

  • 晚上加班不算加班? at 2014年06月12日

    楼主不要纠结这些了,离职就是了。这种公司不值得你浪费时间。

  • Rails Console Tips at 2014年06月09日

    rails console --sandbox 应该只对支持 rollback 的 active record 有效。像 mongodb 这些就不起作用了,因为其本身不支持事务 rollback。另外 command+k,ctrl + r,tab 补全 这些功能,在 console 里面也是一样起作用的。

  • 支持一下吧。看回复,人不多啊,楼主应该考虑去 v2ex 也发一贴。

  • #7 楼 @quakewang 原本看的伤心欲绝的时候,偶然发现一个知音。

  • #8 楼 @donnior 文档不是说了么,一旦你在一个数组上执行 append,系统就会分配一个新的内存空间,创建一个新的数组,然后把数据都 copy 过去,最后将新数组的指针指向那个消息发送者 "a",然后你改变 "a" 的值就已经不影响 b,c 了,因为 b,c 还指向原有的数组内存。

  • 谷歌的网站很难登陆 at 2014年06月04日

    少见多怪。。

  • 放点毒物给大家 at 2014年05月28日

  • #14 楼 @huacnlee 同求 @danoyang 介绍啊。

  • 话说从成都去杭州会不会不适应,楼主以前有没有不适应呢?

  • 好心动啊。好多美女啊!

  • 好想去。

  • 看了 @shooter 的,然后咨询了基友后综合了一下,感觉这个应该比较全了。不全的请大家补充:

    ctrl+p shell 中上一个命令,或者 文本中移动到上一行 ctrl+n shell 中下一个命令,或者 文本中移动到下一行 ctrl+r 往后搜索历史命令 ctrl+s 往前搜索历史命令 ctrl+f 光标前移 ctrl+b 光标后退 ctrl+a 到行首 ctrl+e 到行尾 ctrl+d 删除一个字符,删除一个字符,相当于通常的 Delete 键 ctrl+h 退格删除一个字符,相当于通常的 Backspace 键 ctrl+u 删除到行首 ctrl+k 删除到行尾 ctrl+l 类似 clear 命令效果 ctrl+y 粘贴

    在 mac 下这些命令可以应用到几乎任何地方,文本输入框,shell,和 Emacs 键绑定几乎一致。感觉 HHKB 还是 Emacs 用户最受益了。

    所以楼主还是继续用吧,因为根本不需要方向键啊。哈哈。

  • 刚才咨询好基友后,发现来回查找命令也不发愁了: ctrl+p 上一个命令 ctrl+n 下一个命令 ctrl+r 可以搜索历史命令,很常用的一个 ctrl+a 到行首 ctrl+e 到行尾 ctrl+u 删除到行首 ctrl+k 删除到行尾 ctrl+l 类似 clear 命令效果 ctrl+y 粘贴

    这样 mac 下,貌似确实不需要方向键了。

  • #2 楼 @Victor 我几乎要每天背啊。