【中间件】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
namerota
fd01
sda0
sr01

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字节))
Stringkeyvalue净存量(M)实际存量(M)attach(实-净)(M)单条attach(B)
10w1301.2693.8092.5426.63
-13132.5395.0792.55826.82
-6506.19888.8882.6928.21
-656512.69515.6032.90830.49
20w1302.5397.6185.07926.63
-13135.07810.1585.0826.63
-65012.69517.7775.08226.64
-656525.39130.4755.08427.93
由公式Key+n(field+value+attach)=C求取attach值
 hash 容量估算 =key个数 * [key字节数 + n * (field字节数 + value字节数 + attach(45字节))]
hashkey(B)field(B)value(B)净存量(M)实际存量(M)单条attach(B)
10w13001.2697.228 
-132*1404.00312.545.04
-132*1413*26.54315.04245.36
20w13002.53914.456 
-132*1408.0062545.04
-132*1413*213.08630.11445.44
50w13006.34836.140 
-132*14020.019562.545.04
-132*1413*232.71575.22145.37
list与set类型观察总attach会发现attach是附着在value上的,根据规律得出单条attach的值
list 容量估算 =key字节数 + n * (value字节数 + attach(33字节))
listkeyvalue净存量(B)实际存量(B)总attach(实-净)(B)单条attach(B)
-13100000*1313000134601047330103433
-13200000*1326000139202027660201433
-13300000*13390001313803014990300133
set 容量估算 =key字节数 + n * (value字节数 + attach(25字节))
setkeyvalue净存量(B)实际存量(B)总attach(实-净)(B)单条attach(B)
-13100000*1313000133800852250083925
-13200000*1326000137601664500165125
-13300000*13390001311402476750246325
-100000*130130000072015125901512 
-200000*130260000014403031118030031 

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<String> retList = new ArrayList<String>();//存放遍历出来的数据
        String scanRet = "0";
        do {
            ScanResult<String> 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吧,看压力,动态调整,这个机器吃不消就挪到其它机器上几个实例这样
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值