哈哈
git 的黄金定律之一:公共分支上永远不要做 reset 已经提交的 commit!!!用 revert。
#39 楼 @betterthornbird 当时我们的情况是这样,只有用户名,还有用户的签名里和回复有表情。然后其他地方是没有的。 多数情况下我们的 varchar(255) 类型的,都是存的非常短的内容,比如用户名,这个长度虽然定义了 255,但是到 100 的都没有,当时也是考虑过这个问题的。如果担心有截断,可以在这里 if 判断加上某个表或者某行不处理,或者增加长度,可以做的很灵活,当时我们就是这样处理的。
还有要注意一点!在正式服务器运行的时候,如果表是比较常用的表,比如 user 表,因为需要锁,而且表也比较大的话,可能会卡在那非常久,所以建议处理的时候,有选择处理,还有就是可能会需要避开高峰期。
#37 楼 @betterthornbird 应该会截断的
相当厉害!
@hooopo 你们公司是不是来了一个让你头疼的开发,哈哈
有篇文章介绍在 rails 中如何使用 ActiveRecord + PostgreSQL Materialized Views
感觉这个 gem 不错,可以制定 refresh triggers,指定更新某一行的 materialized_views materialized_views
如果不做计算那就只是一个格式化的操作。sprintf 其实也是一个格式化的操作,你可以自己写一个
def format_number(a)
float_number = a.to_f.to_s.split('.')[1]
size = float_number.size > 2 ? float_number.size : 2
"%.#{size}f" % a
end
咦,怎么当年没有注意到杭州还有这样一家 ruby 公司!
我对面的同学获奖了。
#27 楼 @onemagicant 不需要存,我只关心是否有新的 post,如果有新的 post,获取 post 就可以了,反正 timeline 里还要显示其他内容。
按照你这个代码运行结果:
➜ ~ ruby test.rb
gc: 关闭
time: 2.471569
gc_count: 0
memory: 259.0M
redis used_memory: 12371888
"------------------------------------------------------------"
gc: 关闭
time: 2.339922
gc_count: 0
memory: 246.0M
redis used_memory: 232506256
但是你的数据有严重的倾向。用户 id 在一亿左右,大 v 的粉丝却只有 1000。现在 setbit 的内存消耗时比较多的。但是现在的需求是大 v,所以粉丝少说也得有 100 万。而且大 v 的数量并不影响测试结果。 所以我这里修改为:
user_ids = (100_000_000..100_010_000).to_a
post_ids = [1]
1w 粉丝的时候:
➜ ~ ruby test.rb
gc: 关闭
time: 0.239513
gc_count: 0
memory: 24.0M
redis used_memory: 1250160
"------------------------------------------------------------"
gc: 关闭
time: 0.238195
gc_count: 0
memory: 25.0M
redis used_memory: 16777312
10w 粉丝的时候:
➜ ~ ruby test.rb
gc: 关闭
time: 2.424201
gc_count: 0
memory: 254.0M
redis used_memory: 12248688
"------------------------------------------------------------"
gc: 关闭
time: 2.438514
gc_count: 0
memory: 243.0M
redis used_memory: 16777312
100w 粉丝的时候
➜ ~ ruby test.rb
gc: 关闭
time: 24.655293
gc_count: 0
memory: 2549.0M
redis used_memory: 120388720
"------------------------------------------------------------"
gc: 关闭
time: 26.910435
gc_count: 0
memory: 1847.0M
redis used_memory: 16777568
粉丝数变化 1:10:100 第一种方法:内存变化 1250160:12248688:120388720,约等于 1:10:100。 第二种方法:内存变化 16777312:16777312:16777568,约等于 1:1:1。这个 1 所占内存也跟官方文档介绍的接近 2**26 -1 (8MB allocation)
在用户 id 为 1 亿,粉丝为 100 万的时候,大 v 的存储采用第二种方式比第一张方式内存比 1:7。但是如果大 v 粉丝数是 10 万的时候,内存接近,当粉丝数只有 1w 时,第二种内存消耗更多。不过第二种方案本来也就是出于粉丝太多的情况而设计的。
当有 1 亿用户 id,大 v 有 1000w 粉丝的时候,第一种的大概需要 1140m 内存,第二种方案需要 16m 内存。,大概是 70:1。
因此当大 v 粉丝数,越大越接近用户总数时,第二种方案内存的节省约明显。超过 10 亿用户 id 的时候,这种方法查询时间 30ms 也是可以接受的。但是用户量再大可能查询和设置就会有瓶颈。可以根据系统用户数和粉丝数选择不同方案。
用时间戳存更消耗内存。每个用户都需要有个记录。
#18 楼 @onemagicant http://redis.io/commands/setbit
4294967296 的时候需要 80ms。 268435455 的时候需要 30ms。 67108863 的时候,才 8m 内存,set 需要 8ms。
如果每个用户存一个时间戳,远远不止 8m 内存。
赞!
Indicator | Explanation |
---|---|
%self | 方法本身执行的时间占比,不包括调用的其他的方法执行时间 |
total | 方法执行的总时间,包括调用的其他方法的执行时间 |
self | 方法本身执行的时间,不包括调用的其他的方法执行时间 |
wait | 多线程中,等待其他线程的时间,在单线程程序中,始终为 0 |
child | 方法调用的其他方法的总时间 |
calls | 方法的调用次数 |
之前一直对这里比较模糊,现在一下子清楚了。
@teddy_1004 @vincent 用 setbit 和 getbit 来处理可以不?用大 v 的 id 做 key,使用用户的 id 作为 offset,每次用户获取 timeline 的时候,就 getbit 一次,如果是 1 表示不需要新获取记录,如果是 0 表示有新纪录,获取新纪录后,放到 timeline 的缓存中,然后将 0 置为 1。大 v 每次发新的 post,直接 del 掉 key。
这样数据的存储量要少很多。
我也想试试。https://github.com/u2
听 teahour 介绍过蝉游记,后端终于要扩容了。
赞!
在rack
和grape
里都是通过分配一个常量的方式HTTP_HOST = 'HTTP_HOST'.freeze
来解决这种字符串对象频繁创建的问题。
https://github.com/intridea/grape/blob/master/lib/grape/http/headers.rb
https://github.com/rack/rack/blob/master/lib/rack.rb
非常棒。
非常棒