TDengine 3.0发布已经一段时间,最近在资源受限的硬件上,想测试一下是否可以满足需求。
测试环境:4C8G,Win,TDengine-server-3.0.3.0-Windows-x64,VS2022+.Net6.0
使用的连接器是官方提供就的TDengine.Connector。
测试代码如下:
using System.Diagnostics;
using System.Text;
using TDengineDriver;
//设备数量,每个设备一个独立的线程写入数据
int maxDevices = 8;
//每个设备的Int和Float类型数据项数量,每个数据一张子表
int maxInt = 1_0000;
int maxFloat = 1_0000;
//批写入数量
int maxBatch = 2000;
int totalRecords = 0;
//初始化TDengine数据库
//CREATE DATABASE pascal;
//USE pascal;
//CREATE TABLE IF NOT EXISTS ot(ts timestamp,vint int, vfloat float,vquality int) TAGS (device binary(128),item binary(128),vtype binary(16));
Console.WriteLine($"\r\nbegin maxDevices:{maxDevices},maxBatch:{maxBatch}!\r\n");
for(int i = 0; i < maxDevices; i++)
{
new Thread(() =>
{
ExecWriteJob(i);
}).Start();
}
int lastCount = 0;
Stopwatch swTotal = Stopwatch.StartNew();
while (true)
{
lastCount = totalRecords;
Thread.Sleep(1000);
Console.WriteLine($"totalRecords:{totalRecords},inc:{totalRecords-lastCount},TotalSeconds:{(int)swTotal.Elapsed.TotalSeconds},pcs/sec:{(int)(totalRecords/ swTotal.Elapsed.TotalSeconds)}");
}
Console.WriteLine("\r\n\r\nEnd!");
void ExecWriteJob(int dev)
{
IntPtr conn = GetConnection();
IntPtr res = TDengine.Query(conn, "USE rc");
CheckRes(conn, res, "failed to change database");
while (true)
{
ExecWriteRecords(conn,res,dev);
}
TDengine.Close(conn);
}
void ExecWriteRecords(IntPtr conn, IntPtr res,int dev)
{
int batchCount = 0;
StringBuilder sql = new StringBuilder();
string ts = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}";
{
string devname = $"dev{dev}";
sql.Clear();
sql.Append(" INSERT INTO ");
for (int k = 0; k < maxInt; k++)
{
batchCount++;
Interlocked.Increment(ref totalRecords);
sql.Append($"d{dev}_i_{k:D5} using ot TAGS('{devname}','tag_i_{k}','int') VALUES('{ts}',{Random.Shared.Next()},null,192) ");
if (batchCount >= maxBatch)
{
ExecBatchInsert(conn, res, sql.ToString(), totalRecords);
sql.Clear();
sql.Append(" INSERT INTO ");
batchCount = 0;
}
}
if (batchCount > 0)
{
ExecBatchInsert(conn, res, sql.ToString(), totalRecords);
sql.Clear();
sql.Append(" INSERT INTO ");
batchCount = 0;
}
for (int k = 0; k < maxFloat; k++)
{
batchCount++;
Interlocked.Increment(ref totalRecords);
sql.Append($"d{dev}_f_{k:D5} using ot TAGS('{devname}','tag_f_{k}','float') VALUES ('{ts}',null,{Random.Shared.NextSingle() * 1000},192) ");
if (batchCount >= maxBatch)
{
ExecBatchInsert(conn, res, sql.ToString(), totalRecords);
sql.Clear();
sql.Append(" INSERT INTO ");
batchCount = 0;
}
}
if (batchCount > 0)
{
ExecBatchInsert(conn,res, sql.ToString(), totalRecords);
sql.Clear();
sql.Append(" INSERT INTO ");
batchCount = 0;
}
}
}
void ExecBatchInsert(IntPtr conn, IntPtr res,String sql,int totalRecords)
{
try
{
res = TDengine.Query(conn, sql.ToString());
CheckRes(conn, res, "failed to insert data");
int affectedRows = TDengine.AffectRows(res);
//Console.WriteLine($"affectedRows [{totalRecords}]," + affectedRows);
TDengine.FreeResult(res);
}catch (Exception ex)
{
Console.WriteLine($"ExecBatchInsert [{totalRecords}]ex:" + ex.Message);
}
}
IntPtr GetConnection()
{
string host = "127.0.0.1";
short port = 6030;
string username = "root";
string password = "taosdata";
string dbname = "";
var conn = TDengine.Connect(host, username, password, dbname, port);
if (conn == IntPtr.Zero)
{
throw new Exception("Connect to TDengine failed");
}
else
{
Console.WriteLine("Connect to TDengine success");
}
return conn;
}
void CheckRes(IntPtr conn, IntPtr res, String errorMsg)
{
if (TDengine.ErrorNo(res) != 0)
{
throw new Exception($"{errorMsg} since: {TDengine.Error(res)}");
}
}
测试结果:
开启4线程或8线程时,写入速度约2.5W/S。写入过程中Taos CPU占用较低,客户端CPU占用较高。内存耗用比较低。
使用体验:
使用起来感觉比2.0更加简单,全程没有多少Bug,参考官网示例可以快速完成。
附: