lz4是一種無損壓縮演算法,具有高速解碼與壓縮能力。Log Service部分API介面支援lz4壓縮演算法,使用lz4壓縮演算法可以減少網路傳輸串流量,降低流量費用,提升介面訪問速度。
壓縮請求資料
Log Service如下API介面支援在HTTP請求體中傳輸lz4壓縮格式的資料。
PutLogs(PutLogStoreLogs)
PutWebtracking
其使用方法主要分為如下幾個步驟:
在HTTP要求標頭中添加x-log-compresstype: lz4。
使用lz4壓縮演算法壓縮HTTP請求體。
將HTTP要求標頭中的x-log-bodyrawsize設為請求體壓縮前大小。
將HTTP要求標頭中的Content-Length設為請求體壓縮後大小。
接收壓縮資料
Log Service的PullLogs介面可返回lz4壓縮格式資料。
使用方法:
使用樣本
原始日誌
以log-sample.json的內容作為參考樣本。在實際使用API介面訪問Log Service時,請以實際資料結構為準。
{
"__tags__": {},
"__topic__": "",
"__source__": "47.100.XX.XX",
"__logs__": [
{
"__time__": "03/22 08:51:01",
"content": "*************** RSVP Agent started ***************",
"method": "main",
"level": "INFO"
},
{
"__time__": "03/22 08:51:01",
"content": "Specified configuration file: /u/user10/rsvpd1.conf",
"method": "locate_configFile",
"level": "INFO"
},
{
"__time__": "03/22 08:51:01",
"content": "Using log level 511",
"method": "main",
"level": "INFO"
},
{
"__time__": "03/22 08:51:01",
"content": "Get TCP images rc - EDC8112I Operation not supported on socket",
"method": "settcpimage",
"level": "INFO"
},
{
"__time__": "03/22 08:51:01",
"content": "Associate with TCP/IP image name = TCPCS",
"method": "settcpimage",
"level": "INFO"
},
{
"__time__": "03/22 08:51:02",
"content": "registering process with the system",
"method": "reg_process",
"level": "INFO"
},
{
"__time__": "03/22 08:51:02",
"content": "attempt OS/390 registration",
"method": "reg_process",
"level": "INFO"
},
{
"__time__": "03/22 08:51:02",
"content": "return from registration rc=0",
"method": "reg_process",
"level": "INFO"
}
]
}
測試程式
以Python代碼為例,其壓縮過程如下:
from lz4 import block
with open('log-sample.json', 'rb') as f:
data = f.read()
compressed = block.compress(data, store_size=False) # 壓縮
print(f'out/in: {len(compressed)}/{len(data)} Bytes')
print(f'Compression ratio: {len(compressed)/len(data):.2%}')
壓縮效果
樣本檔案log-sample.json的壓縮測試結果如下所示,壓縮比為39.30%。實際壓縮效果與檔案內容有關,一般來說,內容重複率高的資料有更好的壓縮效果,請以實際壓縮效果為準。
out/in: 542/1379 Bytes
Compression ratio: 39.30%
範例程式碼
Go樣本
安裝依賴庫
go get github.com/pierrec/lz4
範例程式碼
import (
"fmt"
"log"
lz4 "github.com/cloudflare/golz4"
)
func main() {
data := []byte("hello world, hello golang")
// 壓縮
compressed := make([]byte, lz4.CompressBound(data))
compressedSize, err := lz4.Compress(data, compressed)
if err != nil {
log.Fatal(err)
}
compressed = compressed[:compressedSize]
// 解壓
bodyRawSize := len(data) // 解壓Log Service資料,可讀取返回http頭中的x-log-bodyrawsize。
decompressed := make([]byte, bodyRawSize)
err = lz4.Uncompress(compressed, decompressed)
if err != nil {
log.Fatal(err)
}
decompressed = decompressed[:bodyRawSize]
}
Python樣本
安裝依賴庫
python3 -m pip install lz4
範例程式碼
from lz4 import block
data = b'hello world, hello sls'
# 壓縮
compressed = block.compress(data, store_size=False)
# 解壓
body_raw_size=len(data) # 解壓Log Service資料時,可讀取返回http頭中的x-log-bodyrawsize。
decompressed = block.decompress(compressed, uncompressed_size=body_raw_size)
Java樣本
添加Maven依賴
<dependency>
<groupId>net.jpountz.lz4</groupId>
<artifactId>lz4</artifactId>
<version>1.3.0</version>
</dependency>
範例程式碼
package sample;
import net.jpountz.lz4.LZ4Compressor;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4FastDecompressor;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class Sample {
public static void main(String[] args) throws IOException {
byte[] data = "hello world, hello sls".getBytes();
// 壓縮
LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
int maxLen = compressor.maxCompressedLength(data.length);
byte[] buffer = new byte[maxLen];
int compressedSize = compressor.compress(data, 0, data.length, buffer, 0, maxLen);
// 拷貝buffer資料到compressed中。
byte[] compressed = new byte[compressedSize];
System.arraycopy(buffer, 0, compressed, 0, compressedSize);
// 解壓
int bodyRawSize = data.length; // 解壓Log Service資料時,可讀取返回http頭中的x-log-bodyrawsize。
LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
byte[] decompressed = new byte[bodyRawSize];
decompressor.decompress(compressed, 0, decompressed, 0, bodyRawSize);
}
}
JavaScript樣本
使用npm或者yarn安裝依賴庫buffer與lz4。
npm install buffer lz4
範例程式碼
import lz4 from 'lz4'
import { Buffer } from 'buffer'
// 壓縮
const data = 'hello world, hello sls'
const output = Buffer.alloc(lz4.encodeBound(data.length))
const compressedSize = lz4.encodeBlock(Buffer.from(data), output)
const compressed = Uint8Array.prototype.slice.call(output, 0, compressedSize)
// 解壓
const bodyRawSize = data.length; // 解壓Log Service資料時,可讀取返回http頭中的x-log-bodyrawsize。
const decompressed = Buffer.alloc(bodyRawSize)
lz4.decodeBlock(Buffer.from(compressed), decompressed)
const result = decompressed.toString()
C++樣本
將C++ SDK倉庫根目錄下的lz4目錄以及lib目錄拷貝到目標目錄。在編譯時間添加編譯參數,添加lz4庫搜尋路徑(如-L./lib),並連結lz4(如-llz4)。更多資訊,請參見安裝C++ SDK。
g++ -o your_progame your_progame.cpp -std=gnu++11 -llz4 -L./lib/
範例程式碼
#include "lz4/lz4.h"
#include <string>
#include <iostream>
using namespace std;
int main()
{
string data = "hello sls, hello lz4";
// 壓縮
string compressed;
compressed.resize(LZ4_compressBound(data.size()));
int compressed_size = LZ4_compress(data.c_str(), &compressed[0], data.size());
compressed.resize(compressed_size);
// 解壓
string decompressed;
int bodyRawSize = data.size();
decompressed.resize(bodyRawSize);
LZ4_decompress_safe(compressed.c_str(), &decompressed[0], compressed.size(), bodyRawSize);
cout << decompressed << endl;
return 0;
}