存档

2015年4月 的存档

Redis减负之getset

2015年4月28日 没有评论

业务中存在一些跟每个用户相关的数据,高频读写却对精确度要求不高,但也要确保在一定的范围内。数据一般为两种:时间戳或某个自增产生的序号
最初:直接读写DB,业务稍增长后db负载过高。
现状:改为读写redis,value中增加序列号,满千次写一次DB,redis中未命中时读DB。

具体实现方式:
先get,得到xxx.n,当n大于等于1000时,入库set成yyy.1,否则set成yyy.n+1。一个流程中,两次缓存操作,千分之一次DB操作。

今天改为另一种方式:
直接getset yyy, 得到xxx,取yyy和xxx的差值,找一个合理的阈值,超过阈值时触发存储。

优点:
用户数据高频操作时,完全不会写DB,热度降到某个限制以下时,有限的写几次,即:更扛压。原方案用户数据高频操作时写DB必须是同比增加的。

缺点:
确定阈值时麻烦,需要考量高峰和低谷时的情形,去评估主要用户的冷热程度。

需要注意的地方:校验是否需写DB时用的缓存值是上次存入redis,而不是上次存入DB的。如果是时间数据,阈值设置成8小时,不能认为一天就会写三次,实际上中间有阈值内使用时,就会低于三次,甚至如果用户数据操作闲置时间不会低于8小时,就一直不会触发入DB。

分类: 工作 标签: ,

Tomcat中疑似对报文解析异常

2015年4月24日 没有评论

问题描述:
  在WEB应用的日志中,发现把HTTP的HEAD信息全当成KV参数处理了。而且这个KV的尾部还真带着个有效的参数,只是分隔符=已经被URLEncode了。

问题后果:
  我们的应用中会对所有参数做hash校验,参数不对会认为报文无效,被丢弃。直接影响业务功能。
  如果是对参数没校验的应用,结果是丢失HEAD信息后跟的第一个参数,有可能会影响业务功能,除非第一个参数放无用的参数。

解决办法:
  识别出现,删除错误的,解析成正确的加进去。让后续逻辑正常。

问题原因:
  出现的机率相对较小,大概是十万分之一吧。怀疑是用户提交的报文本身就是错的,也可能是nginx转发的时候错了,再或者是Tomcat解析的时候出错了。
  目前看到的KV是以HEAD中charset=utf-8的这个=号作为分隔符的。
  机率太小,就没抓报文去确认是谁的问题。有知道答案的,可以回复我~

分类: 工作 标签: , , ,

MySQL简单查询的默认排序问题

2015年4月20日 没有评论

一个问题的备忘。

测试MySQL版本:5.5.8
测试MySQL存储引擎:InnoDB

初衷:
大表SQL查询按主键正序order by后再limit,速度比较慢,需要优化。

优化过程:
后发现把order by去掉后速度会快非常多,且结果依然正确。

反例被发现:
测试中发现某些特定查询,用到的索引不是主键,默认的顺序是所用到的索引的正序,跟主键的正序不一样。

反例的两个优化推广:
1、如果用到的索引序和主键序完全一样,可以省略order by操作。
2、如果通过主键索引的查询性能优于另一个索引的先排序再limit,可以考虑强制索引:FORCE INDEX (PRIMARY)

欢迎提出推广的反例或其它意见~

分类: 工作 标签: , , , ,