没有怎么用过缓存 数据看板1.2的接口里用到了专业版的接口 他们的改动不频繁 我这里存在根据cinemaIds批量查询影片信息的接口 但是如果是城市大盘的话会存在cinemaIds过多的问题 所以考虑到在我这里加一层索引
加缓存需要注意的问题:
1: 你要考虑的问题是避免热点问题, 比如使用分布式缓存,不要所有的数据缓存到同一台服务器上
2:两外考虑查询场景, 比如以天为单位缓存, 你查询场景是一周的, 这样查询的时候就要查询7次,这样设计是否合理已经满足业务查询性能要求
本地缓存大小主要考虑内存是否够用以及 重启会存在缓存失效,需要重新加载
理论上,已天为key, 天数够多的话,会平均分配到所有的服务器上的 比如365天, 你服务端就3台机器, 理论上每台能分配100多个key,
3: 另外,以天为单位,value值,即cinimaIds是否面临value值过大问题,即刚才说的 每天有多少cinemaIds数据?
4: 是短期缓存,还是永久缓存, 如果短期缓存,可以设置过期时间 ,
5: 另外就是要考虑一下,是否存在缓存失效问题,这属于缓存最基础的问题, 既然缓存就存在不一致或者说失效问题
业务上允许不允许这种不一致
重试
/**
* @param path
* @param value
*
* @return void
*
* @throws InterruptedException
* @throws KeeperException
* @Description: 写PATH数据, 是持久化的
* @author liaoqiqi
* @date 2013-6-14
*/
public void write(String path, String value) throws InterruptedException, KeeperException {
int retries = 0;
while (true) {
try {
Stat stat = zk.exists(path, false);
if (stat == null) {
zk.create(path, value.getBytes(CHARSET), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} else {
zk.setData(path, value.getBytes(CHARSET), stat.getVersion());
}
break;
} catch (KeeperException.SessionExpiredException e) {
throw e;
} catch (KeeperException e) {
LOGGER.warn("write connect lost... will retry " + retries + "\t" + e.toString());
if (retries++ == MAX_RETRIES) {
throw e;
}
// sleep then retry
int sec = RETRY_PERIOD_SECONDS * retries;
LOGGER.warn("sleep " + sec);
TimeUnit.SECONDS.sleep(sec);
}
}
}
这个为啥要重试的时候 都要阶梯性的休眠一会呢
因为 分布式中锁 说白了,还是走网路传输,网络传输又不可靠
就是上面的这种,重试是间隔不是固定的, 随着次数的增加,重试间隔变长
增加重试时间间隔就是为了避开网络问题
比如网络10秒震荡, 你重试间隔2秒,重试三次, 全部重试结束后网络 还没有恢复正常那
如果重试时间间隔依次为2秒,4秒, 8秒, 则三次重试后,网络就恢复正常了
所以 网络震荡越长, 重试时间间隔越长,避免失败后全部重试, 造成雪崩现象
失败后立马进行重试或者固定时间间隔进行重试(短暂时间内流量增场较大), 容易造成雪崩现象, 如果阶梯时重试,随着时间的推移, 重试变得越来越缓慢, 不容易压垮系统