从kafka获取信息写入redis集群

1. 环境

  • kafka kafka-0.10.2.1-src.tgz (asc, md5)
  • redis集群版本: 3.2.1
  • redis服务器:6台, CPU信息 : 8 Intel(R) Xeon(R) CPU E5410 @ 2.33GHz 内存:32G

2. 问题说明

接收GW网关设备发送的radius报文,量级在2000TPS左右,本来想用flume接收udp报文。测试时发现只能使用syslogudp方式,但是解析的报文会丢失很多字段排查后发现flume入库时报文信息被截断了。从git上查到几个udp插件,奈何不搞java了还要编译成jar包遂决定自己写。目前测试了单机从kafka获取数据并解析的效率在3W/s, 加上redis入库后降到1.5w/s

2. kafka连接

本来是想使用travisjeffery/jocko但是发现不支持group,所以使用的confluentinc/confluent-kafka-go 虽然星星不是太多,但是看到这个Confluent's Apache Kafka Golang client你懂的。

使用该模块前,需要安装librdkafka,在安装时遇到

make[1]: 离开目录“/slview/librdkafka-master/src-cpp”
make -C examples
make[1]: 进入目录“/slview/librdkafka-master/examples”
gcc -g -O2 -fPIC -Wall -Wsign-compare -Wfloat-equal -Wpointer-arith -Wcast-align -I../src rdkafka_example.c -o rdkafka_example  \
        ../src/librdkafka.a -lpthread -lz -lssl -lrt
/bin/ld: ../src/librdkafka.a(rdkafka_sasl_scram.o): undefined reference to symbol 'BIO_read'
/bin/ld: note: 'BIO_read' is defined in DSO /usr/local/ssl/lib/libcrypto.so.1.0.0 so try adding it to the linker command line
/usr/local/ssl/lib/libcrypto.so.1.0.0: could not read symbols: 无效的操作
collect2: 错误:ld 返回 1
make[1]: *** [rdkafka_example] 错误 1
make[1]: 离开目录“/slview/librdkafka-master/examples”

google好半天没发现解决方法,最后还是先避开吧。不编译ssl可以成功

./configure --disable-ssl

连接方式:

c, err := kafka.NewConsumer(&kafka.ConfigMap{
        "bootstrap.servers":    broker,
        "group.id":             group,
        "session.timeout.ms":   6000,
        "default.topic.config": kafka.ConfigMap{"auto.offset.reset": "smallest"}})

3. redis连接

redis 3.2在建立集群是使用的内网地址,使用对应的外网地址无法连接,不清是否是配置问题

client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs:        []string{"172.17.50.73:6379", "172.17.50.74:6379", "172.17.50.75:6379", "172.17.50.76:6379", "172.17.50.77:6379", "172.17.50.78:6379"},
ReadOnly:    false,
DialTimeout:  10 * time.Second,
ReadTimeout:  30 * time.Second,
WriteTimeout: 30 * time.Second,
PoolSize:    6000,
PoolTimeout:  30 * time.Second,
})

if client == nil {
return client, ConnectError
}

4. radius报文解析

使用bronze1man/radius模块,代码如下:

radinfo := make(map[string]interface{})

pac, err := radius.DecodePacket(secret, p)
if err != nil {
    log.Println("[pac.Decode]", err)
    return
}

for i := range pac.AVPs {
    Type := pac.AVPs[i].Type
    if Type == radius.EventTimestamp {
        Value := pac.AVPs[i].Decode(pac).([]uint8)
        timestamp := binary.BigEndian.Uint32([]byte(Value))
        timestr := time.Unix(int64(timestamp), 0).Format("2006-01-02 15:04:05")
        Typestr := fmt.Sprintf("%s", Type)
        radinfo[Typestr] = timestr
        //fmt.Printf("Type: %s    Value: %s\n", Type, timestr)
    } else {
        Typestr := fmt.Sprintf("%s", Type)

        if _, ok := Item[Typestr]; ok {
            Value := pac.AVPs[i].GetValue()
            radinfo[Typestr] = Value
        }
    }
}

5. 入库后结果

172.17.50.76:6379> hgetall 86xxxxxxxxxx
 1) "SessionID"
 2) "73aa0e5b1fca2b97"
 3) "APN"
 4) "ctnet"
 5) "Status"
 6) "Stop"
 7) "StartTime"
 8) ""
 9) "MDN"
10) "xxxxxxxxx"
11) "IPAddr"
12) "x.x.x.x"
13) "StopTime"
14) "2017-05-06 14:45:44"
15) "TerminateCause"
16) "UserRequest"
17) "Duration"
18) "2846"
19) "OutputOctets"
20) "0"
21) "InputOctets"
22) "0"

你可能感兴趣的:(从kafka获取信息写入redis集群)