Pika 性能优化

代码星冰乐

专注成就未来

首页 归档 关于

Pika 性能优化

Jan 9, 2019 | haifeiWu | Java | 阅读
文章目录
  1. 1. Pika 是什么
  2. 2. 为什么要进行优化
  3. 3. 具体操作伪代码
    1. 3.1. 方案一
    2. 3.2. 方案二
  4. 4. 小结

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2019/5b7c/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。


由于版权原因,请阅读原文 --> Pika 性能优化

关注我们

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2019/5b7c/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2019/5b7c/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

最近在迁移线上 Redis 到 Pika 的过程中,因为业务需要,需要对项目中原有对 pika 读取操作的代码进行优化,最后结果就是读取百万级的数据由原来的30降低到10分钟左右。

Pika 是什么

Pika 是DBA需求,基础架构组开发的大容量、高性能、持久化、支持多数据结构的类Redis存储系统,目前已经开源,最新版本为 Pika 2.2 版本。它所使用的 nemo 引擎本质上是对Rocksdb的改造和封装,使其支持多数据结构的存储,并在 nemo 引擎之上封装redis接口,使其完全支持 Redis 协议。Pika 兼容 string、hash、list、zset、set 等多数据结构,使用磁盘而非内存存储数据解决了 Redis 由于存储数据量巨大而导致内存不够用的容量瓶颈。这段话摘自官网,感兴趣的小伙伴请转 pika

为什么要进行优化

因为慢啊……,主要是因为单线程的 Redis 是基于内存的,即便是单线程性能也是相当强悍的。Pika 的话是基于磁盘的,相对来说就有点先天不足了,所以多线程访问才能真正发挥它的性能。

具体操作伪代码

业务场景:用户信息已 Hash 的形式存放在 Pika 中,需要根据 Hash 的 Key 获取用户信息,并将用户信息写入文件,数据量在百万级。

方案一

将数据分批,然后将分好批的数据分配给创建的线程,执行获取用户信息,并写入文件的逻辑。下面只是大概的业务逻辑,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Test {
public void businessService() {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0;i < 100; i++) {
executor.submit(new Task());
}
executor.shutdown();
try {
// 等待所有线程
boolean loop;
do {
loop = !executor.awaitTermination(2, TimeUnit.SECONDS);
} while(loop);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("mina thread is over");
}

/**
* 要执行的业务逻辑
*/
class Task implements Runnable {

@Override
public void run() {
// getDataFromPika();
// writeDataToFile();
}
}
}

方案二

将数据读取到阻塞队列中(ArrayBlockingQueue),然后多线程从 ArrayBlockingQueue 中读取数据,写入文件中。线程结束的逻辑就是在队列中读取到特定字符,结束线程。下面是大概的业务逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Test {
private ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1000);

public void businessService() {

// 读取数据,放入到队列中
while (true) {
queue.put("data");
}
ExecutorService executor = Executors.newFixedThreadPool(10);
// 创建线程
for (int i = 0;i < 100; i++) {
executor.submit(new Task());
}

for (int i = 0;i < 100; i++) {
queue.put("STOP");
}

executor.shutdown();
}

/**
* 要执行的业务逻辑
*/
class Task implements Runnable {

@Override
public void run() {
while (true) {
// getDataFromPika();
// writeDataToFile();
if (queue.take() == "STOP") {
break;
}
}

}
}
}

小结

在优化代码是踩了不少坑,原因还是在于自己不够细心,程序员敲代码这活还是比较细的,稍不留意,被自己坑半天。

关注我们

作 者:haifeiWu
原文链接:https://www.hchstudio.cn/article/2019/5b7c/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分享
Java
[划重点] Service 知识要点年 zhong 总结
微信关注我们
分类
  • Android8
  • Go4
  • Java59
  • Kafka,Java1
  • Kotlin2
  • Linux1
  • MapReduce1
  • Python2
  • Raft1
  • Redis1
  • ThreadPoolExecutor1
  • go1
  • 工具1
  • 总结8
  • 旅游日记1
标签
Nginx ChanghuiN haifeiWu Android Java 设计模式 hexo Kotlin 算法 MySQL 源码解析 Python Redis golang web Kafka 配置中心 总结 性能优化 旅游日记 Shell Go 问题排查 译文 Docker Spring Boot 工具 学习笔记 WebFlux 性能测试 go 散列表 源码 netty Raft
最近文章
  • Kafka的日志复制机制
  • 从20到21
  • go 并发编程
  • 【译】了解Linux CPU负载-您何时应该担心?
  • Zookeeper 与分布式锁
  • 基于Redis的分布式锁到底安全吗?
  • 【译】Raft 学生指南
  • ThreadPoolExecutor 的简单梳理
  • MapReduce 的简单实现
  • 使用 Map 实现策略模式
福利专区
    免费SSL证书
      阿里云红包
        腾讯云专属福利
        Copyright © 2021 代码星冰乐. Powered by ChanghuiN. 版权所有 晋ICP备15001365号
        特别感谢: 云服务器服务商 、 CDN 服务商