一个streaming application的性能测试方案在上一篇文章中讲过了,今天讨论了关于输入的流的数据形态是否有影响性能,这一块也要做测试。
因为实际的业务场景的数据生成器还没有要过来,现在就先决定自己写着用。
要考虑的主要是三点:
- 数据的数量,即每秒要产生多少条数据
- 数据的字段多少,例如说wordcount,一行要给几个单词还是几百个单词
- 数据字段的长度,我设计的是给了一个rate,有一定几率给高于多少长度的字符串
经过讨论决定以上面三个参数确定一个数据生成器,产生的数据的处理逻辑,也就是spark streaming的处理逻辑要怎么写也是个问题,因为实际业务还没给只是做个测试。
考虑到做个Wordcount的话每个单词不可能给很长,我提出的方案是生成随机的字符串,长度随机,取特定位置转成整数型,相加取个位数然后进行mapreduce归类。也就是类似于hash的概念。
这样也可以确定操作的粒度,比如说我们还可以取十位和个位,然后再归并等等。
于是就用Java写了数据生成器,因为kafka我还不熟,与kafka的结合就交给学长们干了,我就光写了一个使用tcp套接字传输流数据的一个程序。
分为两个类,一个主类是server端,一个写开辟的线程的操作。
package com.company;
/**
* Created by sunyang on 16/8/25.
*/
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static void main(String[] args) throws Exception{
int port=44444;
int count=100000;//每秒产生多少行数据
int num=10;//每行数据有多少个字段
int length=10;//字段长度的阈值
double rate=0.3;//生成的字段,有多大的比例是比上面给的长度长
double delay=1000.0/count;
//服务端在某个端口监听客户端请求的TCP连接
ServerSocket server = new ServerSocket(port);
Socket client = null;
boolean f = true;
while(f){
//等待客户端的连接,如果没有获取连接
client = server.accept();
System.out.println("与客户端连接成功!");
//为每个客户端连接开启一个线程
new Thread(new ServerThread(client,delay,num,length,rate)).start();
}
server.close();
}
}
package com.company;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Random;
/**
* 该类为多线程类,用于服务端
*/
public class ServerThread implements Runnable {
private Socket client = null;
private double delay = 1000;
private int num=5;
private int length = 10;
private double rate = 0.5;
public ServerThread(Socket client,double delay,int num,int length,double rate){
this.client = client;
this.delay=delay;
this.num=num;
this.length=length;
this.rate=rate;
}
static String nextStr(int num,int length,double rate){
String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random=new Random();
StringBuffer sb=new StringBuffer();
/**
* 一行生成num个数据,用空格隔开
* 有rate比例的数据是大于2*length长度的,其余小于length长度.
*/
for(int i=0;i<num;i++){
if(random.nextDouble()>rate){
int len=random.nextInt(length)+length;
for (int j = 0; j < len; j++) {
int number=random.nextInt(62);
sb.append(str.charAt(number));
}
sb.append(" ");
}
else{
int len=random.nextInt(length);
for (int j = 0; j < len; j++) {
int number=random.nextInt(62);
sb.append(str.charAt(number));
}
sb.append(" ");
}
}
return sb.toString();
}
@Override
public void run() {
System.out.println("客户端的IP地址为: " + client.getInetAddress());
try{
boolean flag=true;
while(flag){
//获取Socket的输出流,用来向客户端发送数据
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
/**
* 如果要求每秒发送条数大于1000,则用delay/1000得到no,用于每次发送no条数据
*/
double no=1;
if(delay<1){
no=1/delay;
delay=1;
}
while(true){
Thread.sleep((int)delay);
for (int i = 0; i < no; i++) {
out.println(nextStr(num,length,rate));
}
out.flush();
}
}
client.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
这样运行以后,使用nc工具,nc localhost 44444