温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

memcached演练(2) 访问memcached服务

发布时间:2020-08-11 07:45:26 来源:网络 阅读:975 作者:randy_shandong 栏目:大数据

通过上节《memcached演练(1) 搭建memcached服务》,已经成功在linux虚拟机上安装了memcached服务,并设置了自启动。

STAT version 1.4.29
Mem:          1891

主要内容

  • 使用telnet命令行工具,操作memcached服务

  • 使用java spymemcached工具访问memcached服务

  • 监控插入不同数据量的数据,响应时间

  • 监控memcached主机繁忙&清闲对比情况

  • 调整memcached的内存指标,插入相同的数据量的数据,什么情况下性能最高

1.使用telnet命令行工具,操作memcached服务

1.1 验证set&add添加命令

[hadoop@hadoop1 ~]$ ps -ef |grep memcached
nobody    2047     1  1 07:27 ?        00:08:59 /usr/local/memcached/bin/memcached -d -p 11211 -u nobody -m 64 -c 1024 -P /var/run/memcached/memcached.pid
hadoop    9037  6485  0 16:59 pts/0    00:00:00 grep memcached
#连接
[hadoop@hadoop1 ~]$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
#获取key1的值
get key1
VALUE key1 0 4
abcd
END
#调用set命令,为一个已存在的key赋值成功
set key1 0 0 4
1234
STORED
get key1
VALUE key1 0 4
1234
END
#调用set命令,为一个已存在的key赋值失败
add key1 0 0 4
abcd
NOT_STORED
get key1
VALUE key1 0 4
1234
END

结论:add和set命令虽然都可以添加数据,但两者使用上存在区别,set可以为已存在的key赋值,而add命令不可以。

1.2 验证get&gets获取命令

#获取1个键值
get key1
VALUE key1 0 4
1234
END
#获取1个键值
get key2
VALUE key2 0 4
word
END
#同时获取2个键值
get key1 key2
VALUE key1 0 4
1234
VALUE key2 0 4
word
END
---------------------------------------------
gets key1
VALUE key1 0 4 7695009
1234
END
gets key2
VALUE key2 0 4 7695010
word
END
gets key1 key2
VALUE key1 0 4 7695009
1234
VALUE key2 0 4 7695010
word
END

#gets命令返回比get命令,多了1个"不知名数字"
#修改key1的值
set key1 0 0 5
world
STORED
#确认变化
get key1
VALUE key1 0 5
world
END
#不知名数字从7695009变为7695011
gets key1
VALUE key1 0 5 7695011
world
END
#key2值没有变化,所以不知名数字也没有变
gets key2
VALUE key2 0 4 7695010
word
END
#再次修改key1的值
set key1 0 0 3
old
STORED
#用增加了1
gets key1 
VALUE key1 0 3 7695012
old
END

结论gets命令比get命令,多返回的数字,类似数据库中的“变更版本号似的”,而且这个版本号是在各键值之间共享。

1.3测试下incr &decr命令

#某key不存在情况
incr seq 1
NOT_FOUND

set seq 0 0 1
1
STORED
get seq 1
VALUE seq 0 1
1
END
incr seq 1
2
...
get seq
VALUE seq 0 1
4
END
gets seq
VALUE seq 0 1 7695016
4
END
incr seq 1
5
#调用incr 命令,增加变更版本号
gets seq
VALUE seq 0 1 7695017
5
END

incr seq 10
15
decr seq 1
14
#不允许为负数
decr seq -1
CLIENT_ERROR invalid numeric delta argument
decr seq 10
4
#最小值为0
decr seq 10
0
#有最大值限制
decr seq 10000000000000000000000
CLIENT_ERROR invalid numeric delta argument
set seq2 0 0 1
a
STORED
#如果键值非数字,会报错
incr seq2 1
CLIENT_ERROR cannot increment or decrement non-numeric value

通过实验验证:incr&decr命令,影响key的长度;最小值为0;增量可变化;必须作用在数字上;命令参数不允许为负数值。

1.4更新命令 append&preppend&replace

set updkey 0 0 5
world
STORED
get updkey
VALUE updkey 0 5
world
END
#在后面添加字符
append updkey 0 0 5
hello
STORED
get updkey
VALUE updkey 0 10
worldhello
#在前面添加字符
prepend updkey 0 0 10
1234567890
STORED
gets updkey
VALUE updkey 0 20 7695030
1234567890worldhello
END
#更改有效时间为1
prepend updkey 0 1 1
#一段时间后,还存在(说明更新操作不会影响有效时间)
get updkey
VALUE updkey 0 22
1u1234567890worldhello
END
#什么都不添加
prepend updkey 0 0 0

STORED
#虽然没有变更值,但变更版本号也发生了变化
gets updkey
VALUE updkey 0 22 7695037
1u1234567890worldhello
#replace命令
replace updkey 0 10 1
m
STORED

get updkey
VALUE updkey 0 1
m
END
#replace命令变更了有效时间
gets updkey
END

结论:prepend 与append命令作用类似,一个在从前面添加字符,一个在后面追加字符。每一次行为,都会影响版本号;不会影响原来的有效时间;replace命令,不仅可以修改数据,而且可以变更有效时间。

还有其他一些指令,就不玩了。


2.使用java spymemcached工具访问memcached服务

2.1 引入依赖

<dependency>
    <groupId>net.spy</groupId>
    <artifactId>spymemcached</artifactId>
    <version>2.11.5</version>
</dependency>

2.2 客户端工具类

package com.nap.memcachedexample.service;
import  net.spy.memcached.MemcachedClient;
import java.io.IOException;
import java.net.InetSocketAddress;

/**
 * Created by Administrator on 2016/8/7.
 */
public class MemcachedUtil {
    private static MemcachedClient cachedClient = null;
    static {
        try {
            cachedClient = new MemcachedClient(new InetSocketAddress("192.168.163.146",11211));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static MemcachedClient getSpyMemcachedClient(){
        return cachedClient;
    }
}

2.2 测试对象

Employee.java  
package com.nap;
import org.apache.commons.lang.builder.ToStringBuilder;
import java.io.Serializable;
import java.util.*;
public class Employee implements Serializable{
    private long empNo;
    private String name;
    private Date birthDate;
    private int age;
    private double salary;
    private List<String> favoriteFoods;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public long getEmpNo() {
        return empNo;
    }

    public void setEmpNo(long empNo) {
        this.empNo = empNo;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public List<String> getFavoriteFoods() {
        return favoriteFoods;
    }

    public void setFavoriteFoods(List<String> favoriteFoods) {
        this.favoriteFoods = favoriteFoods;
    }
    public String toString(){
        return ToStringBuilder.reflectionToString(this);
    }
}
--------------------------------------------------------------------------------------
EmployeeFactory.java 
package com.nap;
import com.nap.memcachedexample.service.MemcachedUtil;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.internal.OperationFuture;
import org.apache.commons.lang.RandomStringUtils;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
public class EmployeeFactory {
    static MemcachedClient mcc = MemcachedUtil.getSpyMemcachedClient();
    public static final String EMPNOSEQ = "empnoseq";

    static{
        Object cacheSeq = mcc.get("empnoseq");
        if(cacheSeq==null){
            OperationFuture<Boolean> seqFuture = mcc.set(EMPNOSEQ, 900, "0");
            try {
                if(seqFuture.get()){
                    System.out.println("set status: ok");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 构造测试对象(一个对象大约40B)
     * @return
     */
    public static Employee newEmployee(){
        long empNo = MemcachedUtil.getSpyMemcachedClient().incr("empnoseq",1);
        Calendar cal = Calendar.getInstance();
        Employee emp = new Employee();
        emp.setEmpNo(empNo);
        emp.setAge(new Random().nextInt(80));
        emp.setName(RandomStringUtils.randomAlphabetic(15));
        cal.set(Calendar.MONTH, new Random().nextInt(30));
        cal.set(Calendar.DAY_OF_YEAR, new Random().nextInt(366));
        emp.setBirthDate(cal.getTime());
        emp.setSalary(new Random().nextFloat());
        List<String> foods = new ArrayList<String>();
        for(int j=0;j< new Random().nextInt(10);j++){
            foods.add("foods_"+RandomStringUtils.randomAlphabetic(10));
        }
        emp.setFavoriteFoods(foods);
        return emp;
    }
}


package com.nap;
import com.nap.memcachedexample.service.MemcachedUtil;
import junit.framework.TestCase;
import net.spy.memcached.MemcachedClient;
import java.util.concurrent.ExecutionException;
public class SpyMemcachedClientTest  extends TestCase
{
    //测试set
    public void testAddBean() throws ExecutionException, InterruptedException {
        MemcachedClient mcc = MemcachedUtil.getSpyMemcachedClient();
        Employee emp = EmployeeFactory.newEmployee();
        System.out.println(emp);
        String key = "emp_" + emp.getEmpNo();
        System.out.println(key);
        mcc.set(key, 19000, emp);
        // Shutdowns the memcached client
        mcc.shutdown();
    }
    //测试get
    public void testGetBean() throws ExecutionException, InterruptedException {
        MemcachedClient mcc = MemcachedUtil.getSpyMemcachedClient();
        Object o = mcc.get("emp_1");
        System.out.println(o);
        // Shutdowns the memcached client
        mcc.shutdown();
    }
}

telnet输出结果

get emp_1
VALUE emp_1 1 345
srcom.nap.Employee
favoriteFoodstLjava/util/List;LnametLjava/lang/String;xpetLjava/util/Date;L

                                                        ?佚U

通过结果分析,通过客户端已经成功保存了。


3.监控插入不同数据量的数据,响应时间

存储单位转换器

package com.nap;
   
public enum SizeConverter {  
    /** 转换任意单位的大小, 返回结果会包含两位小数但不包含单位. */ 
    Arbitrary {  
        @Override 
        public String convert(float size) {  
            while (size > 1024) {  
                size /= 1024;  
            }  
            return String.format(FORMAT_F, size);  
        }  
    },  
       
    // -----------------------------------------------------------------------  
    // 有单位  
    /** 转换单位为B的大小, 返回结果会包含两位小数以及单位. 如: 1024B->1KB, (1024*1024)B->1MB */ 
    B {  
        @Override 
        public String convert(float B) {  
            return converter(0, B);  
        }  
    },  
    /** 转换单位为B的大小, 返回结果会包含两位小数以及单位. */ 
    KB {  
        @Override 
        public String convert(float KB) {  
            return converter(1, KB);  
        }  
    },  
    /** 转换单位为MB的大小, 返回结果会包含两位小数以及单位. */ 
    MB {  
        @Override 
        public String convert(float MB) {  
            return converter(2, MB);  
        }  
    },  
    /** 转换单位为GB的大小, 返回结果会包含两位小数以及单位. */ 
    GB {  
        @Override 
        public String convert(float GB) {  
            return converter(3, GB);  
        }  
    },  
    /** 转换单位为TB的大小, 返回结果会包含两位小数以及单位. */ 
    TB {  
        @Override 
        public String convert(float TB) {  
            return converter(4, TB);  
        }  
    },  
       
    // -----------------------------------------------------------------------  
    // trim没单位  
    /** 转换任意单位的大小, 返回结果小数部分为0时将去除两位小数, 不包含单位. */ 
    ArbitraryTrim {  
        @Override 
        public String convert(float size) {  
            while (size > 1024) {  
                size /= 1024;  
            }  
   
            int sizeInt = (int) size;  
            boolean isfloat = size - sizeInt > 0.0F;  
            if (isfloat) {  
                return String.format(FORMAT_F, size);  
            }  
            return String.format(FORMAT_D, sizeInt);  
        }  
    },  
       
    // -----------------------------------------------------------------------  
    // trim有单位  
    /** 转换单位为B的大小, 返回结果小数部分为0时将去除两位小数, 会包含单位. */ 
    BTrim {  
        @Override 
        public String convert(float B) {  
            return trimConverter(0, B);  
        }  
    },  
    /** 转换单位为KB的大小, 返回结果小数部分为0时将去除两位小数, 会包含单位. */ 
    KBTrim {  
        @Override 
        public String convert(float KB) {  
            return trimConverter(1, KB);  
        }  
    },  
    /** 转换单位为MB的大小, 返回结果小数部分为0时将去除两位小数, 会包含单位. */ 
    MBTrim {  
        @Override 
        public String convert(float MB) {  
            return trimConverter(2, MB);  
        }  
    },  
    /** 转换单位为GB的大小, 返回结果小数部分为0时将去除两位小数, 会包含单位. */ 
    GBTrim {  
        @Override 
        public String convert(float GB) {  
            return trimConverter(3, GB);  
        }  
    },  
    /** 转换单位为TB的大小, 返回结果小数部分为0时将去除两位小数, 会包含单位. */ 
    TBTrim {  
        @Override 
        public String convert(float TB) {  
            return trimConverter(4, TB);  
        }  
    };  
    /*** 
     * <p> 将指定的大小转换到1024范围内的大小. 注意该方法的最大单位为PB, 最小单位为B,  
     * 任何超出该范围的单位最终会显示为**. </p> 
     *  
     * @param size 要转换的大小, 注意是浮点数, 不要以×××的方式传入, 容易造成溢出. 
     *         (如: 1024*1024*1024*1024*1024会溢出, 使结果为0, 因为它先将结果以int相乘后再转换为float;  
     *         而1024.0F*1024.0F*1024.0F*1024.0F*1024.0F就不会溢出) 
     * @return 
     */ 
    abstract public String convert(float size);  
       
    // -----------------------------------------------------------------------  
    // 单位转换  
       
    private static final String[] UNITS = new String[] {  
        "B", "KB", "MB", "GB", "TB", "PB", "**" 
    };  
       
    private static final int LAST_IDX = UNITS.length-1;  
       
    private static final String FORMAT_F = "%1$-1.2f";  
    private static final String FORMAT_F_UNIT = "%1$-1.2f%2$s";  
       
    private static final String FORMAT_D = "%1$-1d";  
    private static final String FORMAT_D_UNIT = "%1$-1d%2$s";  
       
    // -----------------------------------------------------------------------  
    private static String converter(int unit, float size) {  
        int unitIdx = unit;  
        while (size > 1024) {  
            unitIdx++;  
            size /= 1024;  
        }  
        int idx = unitIdx < LAST_IDX ? unitIdx : LAST_IDX;  
        return String.format(FORMAT_F_UNIT, size, UNITS[idx]);  
    }  
       
    private static String trimConverter(int unit, float size) {  
        int unitIdx = unit;  
        while (size > 1024) {  
            unitIdx++;  
            size /= 1024;  
        }  
   
        int sizeInt = (int) size;  
        boolean isfloat = size - sizeInt > 0.0F;  
        int idx = unitIdx < LAST_IDX ? unitIdx : LAST_IDX;  
        if (isfloat) {  
            return String.format(FORMAT_F_UNIT, size, UNITS[idx]);  
        }  
        return String.format(FORMAT_D_UNIT, sizeInt, UNITS[idx]);  
    }  
       
    // -----------------------------------------------------------------------  
    public static String convertBytes(float B, boolean trim) {  
        return trim ? trimConvert(0, B, true) : convert(0, B, true);  
    }  
       
    public static String convertKB(float KB, boolean trim) {  
        return trim ? trimConvert(1, KB, true) : convert(1, KB, true);  
    }  
       
    public static String convertMB(float MB, boolean trim) {  
        return trim ? trimConvert(2, MB, true) : convert(2, MB, true);  
    }  
       
    /*** 
     * <p> 存储大小单位间的转换. 注意该方法的最大单位为PB, 最小单位为B,  
     * 任何超出该范围的单位最终会显示为**. </p> 
     *  
     * @param unit 从哪个单位开始 
     * @param size 存储大小, 注意是float, 不要以×××的形式传入, 否则会溢出(如:1024*1024这种, 
     * 它是先将1024*1024作为int相乘再转换为float的, 如果值过大的话就会溢出了,  
     * 所以这么写1024.0F*1024.0F) 
     * @param withUnit 返回的结果字符串是否带有对应的单位 
     * @return 
     */ 
    private static String convert(int unit, float size, boolean withUnit) {  
        int unitIdx = unit;  
        while (size > 1024) {  
            unitIdx++;  
            size /= 1024;  
        }  
        if (withUnit) {  
            int idx = unitIdx < LAST_IDX ? unitIdx : LAST_IDX;  
            return String.format(FORMAT_F_UNIT, size, UNITS[idx]);  
        }  
        return String.format(FORMAT_F, size);  
    }  
       
    /*** 
     * <p> 存储大小单位间的转换, 如果转换后小数部分为0, 则去除小数部分.  
     * 注意该方法的最大单位为PB, 最小单位为B, 任何超出该范围的单位最终会显示为**. </p> 
     *  
     * @param unit 从哪个单位开始 
     * @param size 存储大小, 注意是float, 不要以×××的形式传入, 否则会溢出(如:1024*1024这种, 
     * 它是先将1024*1024作为int相乘再转换为float的, 如果值过大的话就会溢出了,  
     * 所以这么写1024.0F*1024.0F) 
     * @param withUnit 返回的结果字符串是否带有对应的单位 
     * @return 
     */ 
    private static String trimConvert(int unit, float size, boolean withUnit) {  
        int unitIdx = unit;  
        while (size > 1024) {  
            unitIdx++;  
            size /= 1024;  
        }  
   
        int sizeInt = (int) size;  
        boolean isfloat = size - sizeInt > 0.0F;  
        if (withUnit) {  
            int idx = unitIdx < LAST_IDX ? unitIdx : LAST_IDX;  
            if (isfloat) {  
                return String.format(FORMAT_F_UNIT, size, UNITS[idx]);  
            }  
            return String.format(FORMAT_D_UNIT, sizeInt, UNITS[idx]);  
        }  
   
        if (isfloat) {  
            return String.format(FORMAT_F, size);  
        }  
        return String.format(FORMAT_D, sizeInt);  
    }

    public static void main(String[] args) {
        System.out.println(SizeConverter.BTrim.convert(1029000f));
    }
}


public class SpyMemcachedClientTest  extends TestCase{
//逻辑非常简单,仅仅批量插入数量数据,经过估算一个Employee 对象,一般为40B。
public void testBatchAddBean() throws ExecutionException, InterruptedException {
    MemcachedClient mcc = MemcachedUtil.getSpyMemcachedClient();
    long startTime=System.currentTimeMillis();
    int size=10000000;
    for (int i=0;i<size;i++){
        Employee emp = EmployeeFactory.newEmployee();
        System.out.println(emp);
        mcc.set("emp_" + emp.getEmpNo(), 19000, emp);
    }

    long endTime=System.currentTimeMillis();
    System.out.println("保存对象"+size+"数据大小"+SizeConverter.BTrim.convert(size*40.0f)+";共耗时:"+(endTime-startTime));
    // Shutdowns the memcached client
    mcc.shutdown();
}
}

结论(memcached服务内存参数为64m,每次测试前最好执行下flush,降低换入换出影响)

数据量
数据大小
耗时(ms)
1000
39.06KB1191
10000390.63KB3155
20000781.25KB
5142
30000
1.14MB7057
40000
1.53MB
8611
500001.91MB10611
100000
3.81MB19594
50000019.07MB
89549



通过分析得知,当数据量为10000-20000左右时,单位时间保存的数据最多。

(0.32 kb/ms,降至0.26kb/s)



4.监控memcached主机繁忙&清闲对比情况

由于仅仅考虑写入情况,暂时不需要考虑命中率其他情况。主要记录以下指标

(暂时不考虑内存使用情况,IO等待)

4.1CPU利用率

[root@hadoop1 ~]# sar -u 2 100 
Linux 2.6.32-358.el6.i686 (hadoop1)     08/07/2016      _i686_  (1 CPU)

07:06:47 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
07:06:49 PM     all      0.50      0.00      0.50      0.00      0.00     98.99
07:06:51 PM     all      0.00      0.00      0.51      0.00      0.00     99.49
07:06:53 PM     all      0.00      0.00      0.50      0.00      0.00     99.50
07:06:55 PM     all      0.00      0.00      0.50      0.50      0.00     99.00
---------------start-------------------------------
07:06:57 PM     all      0.00      0.00      5.18      0.00      0.00     94.82
07:06:59 PM     all      0.58      0.00     41.62      0.00      0.00     57.80
07:07:01 PM     all      0.00      0.00     61.69      0.00      0.00     38.31
07:07:03 PM     all      0.65      0.00     65.36      0.00      0.00     33.99
07:07:05 PM     all      0.62      0.00     70.19      0.00      0.00     29.19
07:07:07 PM     all      1.23      0.00     69.14      0.00      0.00     29.63
07:07:09 PM     all      0.00      0.00     70.55      0.00      0.00     29.45
07:07:11 PM     all      0.00      0.00     70.19      0.00      0.00     29.81
07:07:13 PM     all      0.00      0.00     70.81      0.00      0.00     29.19
07:07:15 PM     all      0.00      0.00     70.89      0.00      0.00     29.11
07:07:17 PM     all      0.00      0.00     71.52      0.00      0.00     28.48
07:07:19 PM     all      0.00      0.00     71.60      0.00      0.00     28.40
07:07:21 PM     all      1.27      0.00     69.43      0.00      0.00     29.30
07:07:23 PM     all      0.00      0.00     70.13      0.00      0.00     29.87
07:07:25 PM     all      0.66      0.00     69.74      0.00      0.00     29.61
07:07:27 PM     all      0.00      0.00     71.34      0.00      0.00     28.66
07:07:29 PM     all      1.85      0.00     69.75      0.00      0.00     28.40
07:07:31 PM     all      0.00      0.00     70.81      0.00      0.00     29.19
07:07:33 PM     all      0.00      0.00     70.89      0.00      0.00     29.11
07:07:35 PM     all      0.00      0.00     41.48      0.00      0.00     58.52
-------------------end-----------------------------------------
07:07:37 PM     all      0.00      0.00      0.50      0.00      0.00     99.50
07:07:39 PM     all      0.00      0.00      0.50      0.00      0.00     99.50

在核心级别(kernel)运行所使用 CPU 总时间的百分比突然提升了40%-70%。

相对来说,用户级别的CPU 总时间百分比变化不大。这一点有点出乎意料。

输出项说明:

CPUall 表示统计信息为所有 CPU 的平均值。
%user显示在用户级别(application)运行使用 CPU 总时间的百分比。
%nice显示在用户级别,用于nice操作,所占用 CPU 总时间的百分比。
%system在核心级别(kernel)运行所使用 CPU 总时间的百分比。
%iowait显示用于等待I/O操作占用 CPU 总时间的百分比。
%steal管理程序(hypervisor)为另一个虚拟进程提供服务而等待虚拟 CPU 的百分比。
%idle显示 CPU 空闲时间占用 CPU 总时间的百分比。


4.2换页情况

sar -B
06:59:29 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff

06:59:35 PM      0.00      0.00     15.50      0.00     53.00      0.00      0.00      0.00      0.00
06:59:37 PM      0.00      0.00     15.58      0.00     53.27      0.00      0.00      0.00      0.00
06:59:39 PM      0.00      0.00     15.58      0.00     53.27      0.00      0.00      0.00      0.00
-----start-----------
06:59:41 PM      0.00      0.00     16.76      0.00     61.62      0.00      0.00      0.00      0.00
06:59:43 PM      0.00      0.00    123.78      0.00    111.59      0.00      0.00      0.00      0.00
06:59:45 PM      0.00      0.00     20.25      0.00     92.64      0.00      0.00      0.00      0.00
06:59:47 PM      0.00     22.78     20.89      0.00     94.30      0.00      0.00      0.00      0.00
06:59:49 PM      0.00      0.00     24.84      0.00    105.73      0.00      0.00      0.00      0.00
06:59:51 PM      0.00      0.00     19.02      0.00     92.02      0.00      0.00      0.00      0.00
06:59:53 PM      0.00      0.00     19.50      0.00     93.08      0.00      0.00      0.00      0.00
06:59:55 PM      0.00      0.00     19.38      0.00     95.00      0.00      0.00      0.00      0.00
06:59:57 PM      0.00      0.00    128.12      0.00    123.75      0.00      0.00      0.00      0.00

由于缺少必要的查询操作,换页监控,感觉意义不大。


输出项说明:

pgpgin/s每秒钟从磁盘读入的系统页面的 KB 总数
pgpgout/s每秒钟向磁盘写出的系统页面的 KB 总数
fault/s系统每秒产生的页面失效(major + minor)数量
majflt/s系统每秒产生的页面失效(major)数量


4.3上下文切换次数(提高了2个数量级)

[root@hadoop1 ~]# sar -w 2 100
Linux 2.6.32-358.el6.i686 (hadoop1)     08/07/2016      _i686_  (1 CPU)

06:57:10 PM    proc/s   cswch/s
06:57:12 PM      0.00  14627.04
06:57:14 PM      0.00  14884.81
06:57:16 PM      0.62  14411.11
06:57:18 PM      0.00   1530.41
06:57:20 PM      0.00    118.00
06:57:22 PM      0.00    121.61
06:57:24 PM      0.00    118.09

4.4队列的长度

sar -q
06:10:01 PM   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15
06:20:01 PM         0       230      0.00      0.00      0.00
06:30:01 PM         0       230      0.00      0.00      0.00
06:40:01 PM         0       230      0.00      0.00      0.00
06:50:01 PM         0       230      0.00      0.00      0.00
07:00:01 PM         0       232      0.00      0.00      0.00
07:10:01 PM         0       230      0.00      0.00      0.00
Average:            0       228      0.00      0.00      0.00

基本上没什么变化,可以说明瓶颈不再CPU上。

输出项说明:

runq-sz运行队列的长度(等待运行的进程数)
plist-sz进程列表中进程(processes)和线程(threads)的数量
ldavg-1最后1分钟的系统平均负载(System load average)
ldavg-5过去5分钟的系统平均负载
ldavg-15过去15分钟的系统平均负载


5.调整memcached的内存指标,测试性能


数据量
数据量大小

64m 响应时间

(ms)

128m 响应时间

(ms)

512m响应时间
100039.06KB1191
761
753
10000
390.63KB315531163168
20000
781.25KB5142
49654978
30000
1.14MB
705768936829
40000
1.53MB8611
86298725
50000
1.91MB10611

10660

10334
1000003.81MB19594
1998419760

结论:发现一个奇怪问题。数据量到了40000时,内存大的反而效率低(多次测试,结果不太稳定,这种情况经常发生)。

个人真有点摸不着头脑了,有清楚麻烦告知下。

我分别对比了换入换出指标,CPU利用率情况等,均没有发现能引起注意的地方。难道是网络问题?

本文由于缺少查询操作,所以未考虑命中率,在以后调优演练时补上。

---------------------------

The End

memcached 正常使用了。接下来,借助memcached实现tomcat集群效果

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI