发表于: 2017-09-23 11:26:44

1 750


今天完成的事情:

服务器上安装redis

本来想着找个教程啥的,然后发现redis官网上已经告诉了你怎么安装了

试一下

make完之后它还让我test一下,呵呵

果然出问题了,解决办法是安装tcl

wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz  

sudo tar xzvf tcl8.6.1-src.tar.gz  -C /usr/local/   

cd  /usr/local/tcl8.6.1/unix/   

sudo ./configure   

sudo make   

sudo make install

这个装了好久啊。。然后回去make test,又是好久。。

\O/!

但是现在啥也干不了,因为redis实在前台运行的,除非再开一个shell。看来需要对配置文件进行一些修改了

由于redis.conf这个文件内容实在是太多了,所以我决定把它copy出来修改,再放回去

Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

还有port(默认6379),bind(127.0.0.1),databases(默认16个),protected-mode(保护模式)可以改

之后重启server,这里需要连同配置文件一起启动,可以这样redis-server /opt/redisredis-4.0.2/redis.conf或者直接把redis-server考出来两个放在一起

可以使用了,还提醒我要输入key value,可以

然后打开项目又出现了问题

排查了半天,发现mysql自动关上了,坑啊

测试一下缓存界面

20线程并发10次

在7个线程的时候突然卡死了

问题出在我这个jedis是从连接池中取出来的

Jedis redis=RedisUtil.getJedis();
if(redis.get("users")==null) {
List user = userMapper.userAll();
   redis.set("users".getBytes(), SerializeUtil. serialize(user));
   System.out.println("这是数据库");
   return user;
}else{
System.out.println("这是缓存");
   byte[] value = redis.get("users".getBytes());
   return (List)SerializeUtil. unserialize(value);
}

工具类里有这么一条

//可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private static int MAX_ACTIVE = 1024;

可见最大创建实例个数默认为8,也就是我打开了一个网页算一个,并发了7次,一共八个实例

问题是这个

在源码里这个setMaxActive已经不存在了,可以看到

public int getMaxTotal() {
return this.maxTotal;
}

public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}

public int getMaxIdle() {
return this.maxIdle;
}

public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}

public int getMinIdle() {
return this.minIdle;
}

public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}

被setMaxTotal替代了,怪不得我看都说没用到这个设置,根本不能用好吧_(:з」∠)_

修改之后现在可以创建1000个实例了,在这个之内都没有问题

但是这样子的性能我们可以看到,90%Line是380,很差

我之前忘记返还资源了,现在写成这样

Jedis redis=RedisUtil.getJedis();
if(redis.get("users")==null) {
List user = userMapper.userAll();
   redis.set("users".getBytes(), SerializeUtil. serialize(user));
   System.out.println("这是数据库");
   return user;
}else{
System.out.println("这是缓存");
   byte[] value = redis.get("users".getBytes());
   redis.close();
   return (List)SerializeUtil. unserialize(value);
}

再来测一下

性能好太多了,90%只有155ms,符合标准

可以看到,如果使用连接池的话,不管你连接数设置为多少总会有装满的时候,而且不停的创建新的连接会拖慢项目速度(目测),所以必须要释放资源。

但是不用连接池直接new一个jedis对象的话也没这个问题,但是问题在于,这样做更加浪费系统资源,浪费性能

额,还可以啊,平均值74ms,90%100,再测一下连接池吧

有鬼了,这次又好这么多,90%Line才60,吞吐量高达671.6/s

TPS也很高,稳定后再650左右

测一下负载均衡

20线程并发下,90%Line在1126ms,TPS稳定时在35/s

试了下,只有9线程并发下,90%Line才能在500以下,TPS在35左右

系统宕机时的负载,这个。。

200线程并发

90Line超过了10s,我觉得可以算系统炸了,没人会等这么长时间。

关于缓存穿透,意思是用户查询了一个既不在缓存也不在数据库里的值时,那么系统会现在缓存里查询,再去数据库查询,在高并发情况下这样会加重系统负担,造成系统瘫痪。

我看了之前的代码,可以搞一下

public boolean isRightUser(String user,String password){
System.out.println("输入的账号:" + user + "输入的密码:" + password);
   if (MemcachedUtil.get("users") == null){
System.out.println("查数据库了");
       User user1=userMapper.isRightUser(user,password);
       if (user1 != null){
return true;
       }
}
System.out.println("查缓存");
   return true;

这里输入的账户密码如果数据库没有的话,那么缓存里肯定也没有。

看吧,每次都跳过缓存去查数据库了,缓存没有起到保护数据库的作用。

明天计划的事情:

想爬山之

遇到的问题:

测试这个东西比写代码还费劲


返回列表 返回列表
评论

    分享到