【中间件】pika安装及性能测试

安装机器

环境参数:4cpu 内存8G 磁盘大小250G 
10.19.*.140  主
10.19.*.141  从

磁盘类型判断:rota为1则表示磁盘可旋转,那么就是HDD;如果返回0,则表示磁盘不可以旋转,那么就有可能是SSD。
lsblk -d -o name,rota 执行结果如下:sda为SSD fd0和sr0为HDD
name rota
fd0 1
sda 0
sr0 1

docker启动安装

启动主服务
docker search pika
docker pull pikadb/pika  --拉镜像
vi pika.conf  --进入配置文件修改后台启动daemonize为yes
docker run -it -d  -p 9876:9221 pikadb/pika  --后台启动
docker exec -it containerid bash  --进入容器
./bin/pika -c conf/pika.conf   --进入文件启动pika(启动命令)

启动从服务与主操作基本相同相同,不同点
1.修改启动端口 9877:9221
2.配置主从,进入pika.conf配置文件 进行修改 slaveof ip port

相关启动命令
 docker ps --查看进程
 docker start 9fe26a76668b
 docker stop 9fe26a76668b
 docker restart 9fe26a76668b
 docker kill -s kill 9fe26a76668b 强制杀死
 docker rename containerid newname 重命名容器
 docker inspect 9fe26a76668b 查看容器ip

pika文件存储

内存加磁盘
磁盘文件删除后,要执行flushall才会重建文件

pika docker启动问题处理 

问题1:启动不生效
    docker容器启动的同时内部也要启动
    docker run -it -d  -p 9876:9221 pikadb/pika  --后台启动
    docker exec -it containerid bash  --进入容器
    ./bin/pika -c conf/pika.conf   --进入文件启动pika(启动命令)

问题2:前台启动
    可修改配置文件daemonize为no再启动可查看主从连接情况

问题3:重启主之后,从的连不上
    docker启动时每次启动时iP会修改,所以主启动时要指定ip启动,或是在容器内杀掉进程后启动不会改变ip
        ps -ef|grep pika
        kill -9 47
        ./bin/pika -c conf/pika.conf 

磁盘使用量估算原理

查看文件大小时可执行命令:
echo info | /usr/local/redis/bin/redis-cli -p 9221 | grep db_size_human
由公式key+value+attach=C求取attach值得出以下估算公式
string 容量估算 = key 个数 * (key 字节数 + value 字节数 + attach (30字节))
String key value 净存量(M) 实际存量(M) attach(实-净)(M) 单条attach(B)
10w 13 0 1.269 3.809 2.54 26.63
- 13 13 2.539 5.079 2.558 26.82
- 65 0 6.1988 8.888 2.69 28.21
- 65 65 12.695 15.603 2.908 30.49
20w 13 0 2.539 7.618 5.079 26.63
- 13 13 5.078 10.158 5.08 26.63
- 65 0 12.695 17.777 5.082 26.64
- 65 65 25.391 30.475 5.084 27.93
由公式Key+n(field+value+attach)=C求取attach值
 hash 容量估算 =key个数 * [key字节数 + n * (field字节数 + value字节数 + attach(45字节))]
hash key(B) field(B) value(B) 净存量(M) 实际存量(M) 单条attach(B)
10w 13 0 0 1.269 7.228  
- 13 2*14 0 4.003 12.5 45.04
- 13 2*14 13*2 6.543 15.042 45.36
20w 13 0 0 2.539 14.456  
- 13 2*14 0 8.006 25 45.04
- 13 2*14 13*2 13.086 30.114 45.44
50w 13 0 0 6.348 36.140  
- 13 2*14 0 20.0195 62.5 45.04
- 13 2*14 13*2 32.715 75.221 45.37
list与set类型观察总attach会发现attach是附着在value上的,根据规律得出单条attach的值
list 容量估算 =key字节数 + n * (value字节数 + attach(33字节))
list key value 净存量(B) 实际存量(B) 总attach(实-净)(B) 单条attach(B)
- 13 100000*13 1300013 4601047 3301034 33
- 13 200000*13 2600013 9202027 6602014 33
- 13 300000*13 3900013 13803014 9903001 33
set 容量估算 =key字节数 + n * (value字节数 + attach(25字节))
set key value 净存量(B) 实际存量(B) 总attach(实-净)(B) 单条attach(B)
- 13 100000*13 1300013 3800852 2500839 25
- 13 200000*13 2600013 7601664 5001651 25
- 13 300000*13 3900013 11402476 7502463 25
- 100000*13 0 1300000 7201512 5901512  
- 200000*13 0 2600000 14403031 118030031  

pika超时机制

现象1:key设置过期时间,删除数据后,会发现文件中的数据没有删除掉,再存入新的相同的key也可以存入
现象2:相同的key在硬盘中不会覆盖,可以获取到最新的

原因:数据在存储时在数据末尾加上了用于记录的时间戳,如果时间戳里记录的时间比当前时间要小,说明数据已经过去,这时候就不会返回给上层,但是实际的数据可能还存db层。

引发问题:如何清理过期数据?
解决方法:手动删除使用compact会统一删除过期数据

compact介绍:
1.自动全量的compact:通过配置的参数每天定时触发一次自动全量compact,特别适合存在多数据结构。参数结构:“启动时间(小时)-结束时间(小时)、磁盘空间空余空间百分比”,例如需要配置一个每天在凌晨,同时该任务仅仅在磁盘空余时间不低于30%的时候执行,那么应配置为:03-04/30,该参数默认为空
2.自动全量compact,和compact-cron区别为,compact-cron每天仅在指定时间段执行,而compact循环执行,例如需要配置一个每4个小时执行一次的自动compact任务,同时该任务仅仅在磁盘空余空间应配置为:4/30该默认参数为空
3.compact期间可能会额外占用磁盘空间, 连接数不会增加,约要预留db大小的20%给compact

底层会在某些时候触发局部compact, 也可以在Pika端执行compact命令手动触发全局compact(同一个Key的记录,以Sequence Number最大的那个为准)

主从数据同步时间测试

前提:服务器上本地运行(为了防止有网络传输影响)
主输入10w数据完成开始,到从服务读取到主服务输入的最后一个数据的时间差1548667123413-1548667123409=4ms
    此数据不一定代表主从同步的时间,待进一步验证
        for (int i=0;i<100000;i++){
			String s=StringUtils.leftPad(i+"",12,"0");
			String key = "y"+s;
			masterRedisPoolFactory.setValue(key,key);
		}
		System.out.println(System.currentTimeMillis());
		while(true){
			String s=slaveRedisPoolFactory.getValue("y0000000100000");
			if (s!=null){
				break;
			}
		}
		System.out.println(System.currentTimeMillis());

百万数据遍历时间测试

前提:服务器上本地运行(为了防止有网络传输影响)
遍历数据使用的scan命令,每次查询10万条数据,共查询100万,执行10次,平均遍历速度100万/467ms
        Long start = System.currentTimeMillis();
        Jedis jedis=slaveRedisPoolFactory.getJedis();
        ScanParams scanParams = new ScanParams();
        scanParams.count(100000);//每10万条查询
        Long startTime = System.currentTimeMillis();
        List retList = new ArrayList();//存放遍历出来的数据
        String scanRet = "0";
        do {
            ScanResult ret = jedis.scan(scanRet,scanParams);
            scanRet = ret.getStringCursor();// 返回用于下次遍历的游标
            retList.addAll(ret.getResult());// 返回结果
        } while (!scanRet.equals("1000000"));
        Long endTime = System.currentTimeMillis();
        log.info("retList size:[{}],using time is:[{}]ms",retList.size(),(endTime - startTime));

线上问题(暂未验证)

问题1.Get child directory when try to do db sync failed线上报这个错,slave同步不了
answer:
    这个过程就是pika全量同步并转换为增量同步的过程:
    是把dump目录整个拷到slave替换掉db目录,然后启动从库,查看info文件,记录里面的同步位置,然后通过slaveof指定该位置同步
    
问题2.Pika对一个Key反复写入确实可能会导致硬盘占用持续增长

问题3.写入量很大,然后一段时间之后卡死,server直接hang死 ,重启后 rocksdb进程仍占99.9%cpu?
iostat -mxt 1 (磁盘为SSD盘)查看await的值(一般达到10已经为上限)
这个问题可以这样解释:写入数据的速度大于rocksdb的memtable的刷盘速度,IO吃不消
而没有及时刷盘的memtable不断的积压,最终达到了写保护的阈值,造成写入hang死。然后这个时候仍然有很多memtable没刷盘,此时实例被重启,然后启动的时候rocksdb需要通过WAL来处理这些数据,然后就是现在看到的样子,但现在磁盘还是吃不消的样子,所以这个意外重启的恢复估计还要跑一阵

一台机器一般3~10个pika吧,看压力,动态调整,这个机器吃不消就挪到其它机器上几个实例这样

你可能感兴趣的:(【中间件】pika安装及性能测试)