Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
apache
Iotdb
提交
8445b08c
I
Iotdb
项目概览
apache
/
Iotdb
10 个月 前同步成功
通知
25
Star
3344
Fork
916
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
Iotdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
8445b08c
编写于
12月 30, 2017
作者:
J
jt2594838
提交者:
XuYi
12月 30, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Write memory control (#196)
上级
56a79762
变更
32
隐藏空白更改
内联
并排
Showing
32 changed file
with
1781 addition
and
40 deletion
+1781
-40
iotdb/conf/iotdb-engine.properties
iotdb/conf/iotdb-engine.properties
+23
-6
iotdb/conf/iotdb-env.sh
iotdb/conf/iotdb-env.sh
+1
-0
iotdb/conf/logback.xml
iotdb/conf/logback.xml
+1
-1
pom.xml
pom.xml
+2
-2
src/main/java/cn/edu/tsinghua/iotdb/conf/TsFileDBConstant.java
...ain/java/cn/edu/tsinghua/iotdb/conf/TsFileDBConstant.java
+10
-1
src/main/java/cn/edu/tsinghua/iotdb/conf/TsfileDBConfig.java
src/main/java/cn/edu/tsinghua/iotdb/conf/TsfileDBConfig.java
+45
-0
src/main/java/cn/edu/tsinghua/iotdb/conf/TsfileDBDescriptor.java
...n/java/cn/edu/tsinghua/iotdb/conf/TsfileDBDescriptor.java
+20
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/Processor.java
src/main/java/cn/edu/tsinghua/iotdb/engine/Processor.java
+4
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/bufferwrite/BufferWriteProcessor.java
...inghua/iotdb/engine/bufferwrite/BufferWriteProcessor.java
+95
-24
src/main/java/cn/edu/tsinghua/iotdb/engine/filenode/FileNodeManager.java
...n/edu/tsinghua/iotdb/engine/filenode/FileNodeManager.java
+80
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/filenode/FileNodeProcessor.java
...edu/tsinghua/iotdb/engine/filenode/FileNodeProcessor.java
+22
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/flushthread/FlushManager.java
...n/edu/tsinghua/iotdb/engine/flushthread/FlushManager.java
+11
-1
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/BasicMemController.java
.../tsinghua/iotdb/engine/memcontrol/BasicMemController.java
+68
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/FlushPartialPolicy.java
.../tsinghua/iotdb/engine/memcontrol/FlushPartialPolicy.java
+38
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/ForceFLushAllPolicy.java
...tsinghua/iotdb/engine/memcontrol/ForceFLushAllPolicy.java
+37
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/JVMMemController.java
...du/tsinghua/iotdb/engine/memcontrol/JVMMemController.java
+85
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemMonitorThread.java
...du/tsinghua/iotdb/engine/memcontrol/MemMonitorThread.java
+60
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemStatisticThread.java
.../tsinghua/iotdb/engine/memcontrol/MemStatisticThread.java
+63
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/NoActPolicy.java
.../cn/edu/tsinghua/iotdb/engine/memcontrol/NoActPolicy.java
+15
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/Policy.java
.../java/cn/edu/tsinghua/iotdb/engine/memcontrol/Policy.java
+8
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/RecordMemController.java
...tsinghua/iotdb/engine/memcontrol/RecordMemController.java
+116
-0
src/main/java/cn/edu/tsinghua/iotdb/engine/overflow/io/OverflowProcessor.java
.../tsinghua/iotdb/engine/overflow/io/OverflowProcessor.java
+98
-1
src/main/java/cn/edu/tsinghua/iotdb/utils/MemUtils.java
src/main/java/cn/edu/tsinghua/iotdb/utils/MemUtils.java
+89
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/ProcessorTest.java
...test/java/cn/edu/tsinghua/iotdb/engine/ProcessorTest.java
+14
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/BufferwriteFileSizeControlTest.java
...tdb/engine/memcontrol/BufferwriteFileSizeControlTest.java
+139
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/BufferwriteMetaSizeControlTest.java
...tdb/engine/memcontrol/BufferwriteMetaSizeControlTest.java
+139
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemControlTest.java
.../edu/tsinghua/iotdb/engine/memcontrol/MemControlTest.java
+173
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemControllerTest.java
...u/tsinghua/iotdb/engine/memcontrol/MemControllerTest.java
+75
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/OverflowFileSizeControlTest.java
.../iotdb/engine/memcontrol/OverflowFileSizeControlTest.java
+115
-0
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/OverflowMetaSizeControlTest.java
.../iotdb/engine/memcontrol/OverflowMetaSizeControlTest.java
+115
-0
src/test/java/cn/edu/tsinghua/iotdb/service/LargeDataTest.java
...est/java/cn/edu/tsinghua/iotdb/service/LargeDataTest.java
+4
-4
src/test/java/cn/edu/tsinghua/iotdb/service/TestUtils.java
src/test/java/cn/edu/tsinghua/iotdb/service/TestUtils.java
+16
-0
未找到文件。
iotdb/conf/iotdb-engine.properties
浏览文件 @
8445b08c
...
...
@@ -56,12 +56,12 @@ period_time_for_merge_in_second=7200
# default value is +08:00
# eg. +08:00, -01:00
time_zone
=
+08:00
# if memory used by write reaches this threshold, auto flush will be triggered, percentile of Java heap memory
mem_threshold_warning
=
0.8
# if memory used by write reaches this threshold, auto flush will be triggered, in byte, 8GB by default
mem_threshold_warning
=
23622320128
# if memory used by write reaches this threshold, write will be blocked, in byte, 16GB by default
mem_threshold_dangerous
=
25769803776
# if memory used by write reaches this threshold, write will be blocked, percentile of Java heap memory
mem_threshold_dangerous
=
0.9
# every such interval, a thread will check if memory exceeds mem_threshold_warning
# if do exceed, auto flush will be triggered, in ms, 1s by default
...
...
@@ -72,8 +72,25 @@ mem_monitor_interval=1000
# 1 is JVMMemController, which use JVM heap memory as threshold.
mem_controller_type
=
1
# When a bufferwrite's metadata size (in byte) exceed this, the bufferwrite is forced closed.
bufferwrite_meta_size_threshold
=
209715200
# When a bufferwrite's file size (in byte) exceed this, the bufferwrite is forced closed.
bufferwrite_file_size_threshold
=
2147483648
# When a overflow's metadata size (in byte) exceed this, the bufferwrite is forced closed.
overflow_meta_size_threshold
=
209715200
# When a overflow's file size (in byte) exceed this, the bufferwrite is forced closed.
overflow_file_size_threshold
=
2147483648
# How many thread can concurrently flush. When <= 0, use CPU core number.
concurrent_flush_thread
=
0
# Statistics Monitor configuration
# default monitor is enabled, and write statistics info to IoTDB every 5 seconds
# Choose to change the back_loop_period >= 1 seconds
enable_stat_monitor
=
true
back_loop_period
=
5
\ No newline at end of file
back_loop_period
=
5
iotdb/conf/iotdb-env.sh
浏览文件 @
8445b08c
...
...
@@ -110,5 +110,6 @@ fi
IOTDB_DERBY_OPTS
=
"-Dderby.stream.error.field=cn.edu.tsinghua.iotdb.auth.dao.DerbyUtil.DEV_NULL"
IOTDB_JMX_OPTS
=
"
$IOTDB_JMX_OPTS
-Xloggc:
${
IOTDB_HOME
}
/gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails"
IOTDB_JMX_OPTS
=
"
$IOTDB_JMX_OPTS
-Xms
${
HEAP_NEWSIZE
}
"
IOTDB_JMX_OPTS
=
"
$IOTDB_JMX_OPTS
-Xmx
${
MAX_HEAP_SIZE
}
"
iotdb/conf/logback.xml
浏览文件 @
8445b08c
...
...
@@ -96,7 +96,7 @@
<logger
name=
"cn.edu.tsinghua.iotdb.service"
level=
"info"
/>
<logger
name=
"cn.edu.tsinghua.iotdb.conf"
level=
"info"
/>
<root
level=
"
ERROR
"
>
<root
level=
"
info
"
>
<appender-ref
ref=
"FILEDEBUG"
/>
<appender-ref
ref=
"FILEINFO"
/>
<appender-ref
ref=
"FILEWARN"
/>
...
...
pom.xml
浏览文件 @
8445b08c
...
...
@@ -4,7 +4,7 @@
<groupId>
cn.edu.tsinghua
</groupId>
<artifactId>
IoTDB
</artifactId>
<version>
0.
3.1
</version>
<version>
0.
4.0
</version>
<packaging>
jar
</packaging>
<name>
IoTDB
</name>
...
...
@@ -23,7 +23,7 @@
<dependency>
<groupId>
cn.edu.tsinghua
</groupId>
<artifactId>
iotdb-jdbc
</artifactId>
<version>
0.
3.1
</version>
<version>
0.
4.0
</version>
</dependency>
<dependency>
<groupId>
cn.edu.fudan.dsm
</groupId>
...
...
src/main/java/cn/edu/tsinghua/iotdb/conf/TsFileDBConstant.java
浏览文件 @
8445b08c
...
...
@@ -4,12 +4,21 @@ public class TsFileDBConstant {
public
static
final
String
ENV_FILE_NAME
=
"iotdb-env"
;
public
static
final
String
IOTDB_CONF
=
"IOTDB_CONF"
;
public
static
final
String
GLOBAL_DB_NAME
=
"IoTDB"
;
public
static
final
String
VERSION
=
"0.
3.1
"
;
public
static
final
String
VERSION
=
"0.
4.0
"
;
public
static
final
String
REMOTE_JMX_PORT_NAME
=
"com.sun.management.jmxremote.port"
;
public
static
final
String
TSFILEDB_LOCAL_JMX_PORT_NAME
=
"iotdb.jmx.local.port"
;
public
static
final
String
TSFILEDB_REMOTE_JMX_PORT_NAME
=
"iotdb.jmx.remote.port"
;
public
static
final
String
SERVER_RMI_ID
=
"java.rmi.server.randomIDs"
;
public
static
final
String
RMI_SERVER_HOST_NAME
=
"java.rmi.server.hostname"
;
public
static
final
String
JMX_REMOTE_RMI_PORT
=
"com.sun.management.jmxremote.rmi.port"
;
public
static
final
long
GB
=
1024
*
1024
*
1024L
;
public
static
final
long
MB
=
1024
*
1024L
;
public
static
final
long
KB
=
1024L
;
public
static
final
long
MEM_THRESHOLD_WARNING_DEFAULT
=
8
*
GB
;
public
static
final
long
MEM_THRESHOLD_DANGEROUS_DEFAULT
=
16
*
GB
;
public
static
final
String
IOTDB_HOME
=
"IOTDB_HOME"
;
}
src/main/java/cn/edu/tsinghua/iotdb/conf/TsfileDBConfig.java
浏览文件 @
8445b08c
...
...
@@ -117,6 +117,50 @@ public class TsfileDBConfig {
public
DateTimeZone
timeZone
=
DateTimeZone
.
getDefault
();
/**
* BufferWriteProcessor and OverflowProcessor will immediately flush if this threshold is reached.
*/
public
long
memThresholdWarning
=
(
long
)
(
0.8
*
Runtime
.
getRuntime
().
maxMemory
());
/**
* No more insert is allowed if this threshold is reached.
*/
public
long
memThresholdDangerous
=
(
long
)
(
0.9
*
Runtime
.
getRuntime
().
maxMemory
());
/**
* MemMonitorThread will check every such interval. If memThresholdWarning is reached, MemMonitorThread
* will inform FileNodeManager to flush.
*/
public
long
memMonitorInterval
=
1000
;
// in ms
/**
* Decide how to control memory used by inserting data.
* 0 is RecordMemController, which count the size of every record (tuple).
* 1 is JVMMemController, which use JVM heap memory as threshold.
*/
public
int
memControllerType
=
1
;
/**
* When a bufferwrite's metadata size (in byte) exceed this, the bufferwrite is forced closed.
*/
public
long
bufferwriteMetaSizeThreshold
=
200
*
1024
*
1024L
;
/**
* When a bufferwrite's file size (in byte) exceed this, the bufferwrite is forced closed.
*/
public
long
bufferwriteFileSizeThreshold
=
2
*
1024
*
1024
*
1024L
;
/**
* When a overflow's metadata size (in byte) exceed this, the overflow is forced closed.
*/
public
long
overflowMetaSizeThreshold
=
200
*
1024
*
1024L
;
/**
* When a overflow's file size (in byte) exceed this, the overflow is forced closed.
*/
public
long
overflowFileSizeThreshold
=
2
*
1024
*
1024
*
1024L
;
/*
* The statMonitor's BackLoop period, 5s is enough
*/
public
int
backLoopPeriod
=
5
;
...
...
@@ -129,6 +173,7 @@ public class TsfileDBConfig {
* the maximum number of writing instances existing in same time.
*/
public
TsfileDBConfig
()
{}
public
void
updateDataPath
()
{
...
...
src/main/java/cn/edu/tsinghua/iotdb/conf/TsfileDBDescriptor.java
浏览文件 @
8445b08c
...
...
@@ -7,6 +7,7 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.util.Properties
;
import
cn.edu.tsinghua.iotdb.engine.memcontrol.BasicMemController
;
import
org.joda.time.DateTimeZone
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -87,6 +88,25 @@ public class TsfileDBDescriptor {
conf
.
periodTimeForFlush
=
Long
.
parseLong
(
properties
.
getProperty
(
"period_time_for_flush_in_second"
,
conf
.
periodTimeForFlush
+
""
).
trim
());
conf
.
periodTimeForMerge
=
Long
.
parseLong
(
properties
.
getProperty
(
"period_time_for_merge_in_second"
,
conf
.
periodTimeForMerge
+
""
).
trim
());
conf
.
memThresholdWarning
=
(
long
)
(
Runtime
.
getRuntime
().
maxMemory
()
*
Double
.
parseDouble
(
properties
.
getProperty
(
"mem_threshold_warning"
,
conf
.
memThresholdWarning
+
""
).
trim
())
);
conf
.
memThresholdDangerous
=
(
long
)
(
Runtime
.
getRuntime
().
maxMemory
()
*
Double
.
parseDouble
(
properties
.
getProperty
(
"mem_threshold_dangerous"
,
conf
.
memThresholdDangerous
+
""
).
trim
()));
conf
.
memMonitorInterval
=
Long
.
parseLong
(
properties
.
getProperty
(
"mem_monitor_interval"
,
conf
.
memMonitorInterval
+
""
).
trim
());
conf
.
memControllerType
=
Integer
.
parseInt
(
properties
.
getProperty
(
"mem_controller_type"
,
conf
.
memControllerType
+
""
).
trim
());
conf
.
memControllerType
=
conf
.
memControllerType
>=
BasicMemController
.
CONTROLLER_TYPE
.
values
().
length
?
0
:
conf
.
memControllerType
;
conf
.
bufferwriteMetaSizeThreshold
=
Long
.
parseLong
(
properties
.
getProperty
(
"bufferwrite_meta_size_threshold"
,
conf
.
bufferwriteMetaSizeThreshold
+
""
).
trim
());
conf
.
bufferwriteFileSizeThreshold
=
Long
.
parseLong
(
properties
.
getProperty
(
"bufferwrite_file_size_threshold"
,
conf
.
bufferwriteFileSizeThreshold
+
""
).
trim
());
conf
.
overflowMetaSizeThreshold
=
Long
.
parseLong
(
properties
.
getProperty
(
"overflow_meta_size_threshold"
,
conf
.
overflowMetaSizeThreshold
+
""
).
trim
());
conf
.
overflowFileSizeThreshold
=
Long
.
parseLong
(
properties
.
getProperty
(
"overflow_file_size_threshold"
,
conf
.
overflowFileSizeThreshold
+
""
).
trim
());
if
(
conf
.
memThresholdWarning
<=
0
)
conf
.
memThresholdWarning
=
TsFileDBConstant
.
MEM_THRESHOLD_WARNING_DEFAULT
;
if
(
conf
.
memThresholdDangerous
<
conf
.
memThresholdWarning
)
conf
.
memThresholdDangerous
=
Math
.
max
(
conf
.
memThresholdWarning
,
TsFileDBConstant
.
MEM_THRESHOLD_DANGEROUS_DEFAULT
);
conf
.
concurrentFlushThread
=
Integer
.
parseInt
(
properties
.
getProperty
(
"concurrent_flush_thread"
,
conf
.
concurrentFlushThread
+
""
));
if
(
conf
.
concurrentFlushThread
<=
0
)
conf
.
concurrentFlushThread
=
Runtime
.
getRuntime
().
availableProcessors
();
...
...
src/main/java/cn/edu/tsinghua/iotdb/engine/Processor.java
浏览文件 @
8445b08c
...
...
@@ -155,6 +155,8 @@ public abstract class Processor {
*/
public
abstract
boolean
canBeClosed
();
public
abstract
void
flush
()
throws
IOException
;
/**
* Close the processor.<br>
* Notice: Thread is not safe
...
...
@@ -163,4 +165,6 @@ public abstract class Processor {
* @throws ProcessorException
*/
public
abstract
void
close
()
throws
ProcessorException
;
public
abstract
long
memoryUsage
();
}
src/main/java/cn/edu/tsinghua/iotdb/engine/bufferwrite/BufferWriteProcessor.java
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.bufferwrite
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.RandomAccessFile
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.Set
;
import
java.util.concurrent.locks.ReadWriteLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
import
org.joda.time.DateTime
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.engine.Processor
;
import
cn.edu.tsinghua.iotdb.engine.flushthread.FlushManager
;
import
cn.edu.tsinghua.iotdb.engine.memcontrol.BasicMemController
;
import
cn.edu.tsinghua.iotdb.engine.utils.FlushState
;
import
cn.edu.tsinghua.iotdb.exception.BufferWriteProcessorException
;
import
cn.edu.tsinghua.iotdb.exception.PathErrorException
;
import
cn.edu.tsinghua.iotdb.metadata.ColumnSchema
;
import
cn.edu.tsinghua.iotdb.metadata.MManager
;
import
cn.edu.tsinghua.iotdb.sys.writelog.WriteLogManager
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileConfig
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileDescriptor
;
import
cn.edu.tsinghua.tsfile.common.constant.JsonFormatConstant
;
...
...
@@ -51,6 +32,17 @@ import cn.edu.tsinghua.tsfile.timeseries.write.record.DataPoint;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.TSRecord
;
import
cn.edu.tsinghua.tsfile.timeseries.write.schema.FileSchema
;
import
cn.edu.tsinghua.tsfile.timeseries.write.series.IRowGroupWriter
;
import
org.joda.time.DateTime
;
import
org.json.JSONArray
;
import
org.json.JSONObject
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.io.*
;
import
java.util.*
;
import
java.util.Map.Entry
;
import
java.util.concurrent.locks.ReadWriteLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
public
class
BufferWriteProcessor
extends
Processor
{
...
...
@@ -84,6 +76,8 @@ public class BufferWriteProcessor extends Processor {
private
Action
bufferwriteCloseAction
=
null
;
private
Action
filenodeFlushAction
=
null
;
private
long
memUsed
=
0
;
public
BufferWriteProcessor
(
String
processorName
,
String
fileName
,
Map
<
String
,
Object
>
parameters
)
throws
BufferWriteProcessorException
{
super
(
processorName
);
...
...
@@ -472,7 +466,25 @@ public class BufferWriteProcessor extends Processor {
public
void
write
(
TSRecord
tsRecord
)
throws
BufferWriteProcessorException
{
try
{
recordWriter
.
write
(
tsRecord
);
long
newMemUsage
=
MemUtils
.
getTsRecordMemBufferwrite
(
tsRecord
);
BasicMemController
.
UsageLevel
level
=
BasicMemController
.
getInstance
().
reportUse
(
this
,
newMemUsage
);
switch
(
level
)
{
case
SAFE:
recordWriter
.
write
(
tsRecord
);
memUsed
+=
newMemUsage
;
break
;
case
WARNING:
LOGGER
.
debug
(
"Memory usage will exceed warning threshold, current : {}."
,
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()));
recordWriter
.
write
(
tsRecord
);
memUsed
+=
newMemUsage
;
break
;
case
DANGEROUS:
default
:
LOGGER
.
warn
(
"Memory usage will exceed dangerous threshold, current : {}."
,
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()));
throw
new
BufferWriteProcessorException
(
"Memory usage exceeded dangerous threshold."
);
}
}
catch
(
IOException
|
WriteProcessException
e
)
{
LOGGER
.
error
(
"Write TSRecord error, the TSRecord is {}, the bufferwrite is {}."
,
tsRecord
,
getProcessorName
());
...
...
@@ -516,6 +528,11 @@ public class BufferWriteProcessor extends Processor {
}
}
@Override
public
void
flush
()
throws
IOException
{
recordWriter
.
flushRowGroup
(
false
);
}
@Override
public
void
close
()
throws
BufferWriteProcessorException
{
isFlushingSync
=
true
;
...
...
@@ -536,7 +553,11 @@ public class BufferWriteProcessor extends Processor {
}
finally
{
isFlushingSync
=
false
;
}
}
@Override
public
long
memoryUsage
(){
return
recordWriter
.
calculateMemSizeForAllGroup
();
}
public
void
addTimeSeries
(
String
measurementToString
,
String
dataType
,
String
encoding
,
String
[]
encodingArgs
)
...
...
@@ -608,6 +629,8 @@ public class BufferWriteProcessor extends Processor {
}
}
}
long
oldMemUsage
=
memUsed
;
memUsed
=
0
;
// update the lastUpdatetime
try
{
bufferwriteFlushAction
.
act
();
...
...
@@ -643,6 +666,8 @@ public class BufferWriteProcessor extends Processor {
// handle
throw
new
IOException
(
e
);
}
BasicMemController
.
getInstance
().
reportFree
(
BufferWriteProcessor
.
this
,
oldMemUsage
);
checkSize
();
}
else
{
flushState
.
setFlushing
();
switchIndexFromWorkToFlush
();
...
...
@@ -690,6 +715,8 @@ public class BufferWriteProcessor extends Processor {
}
finally
{
convertBufferLock
.
writeLock
().
unlock
();
}
BasicMemController
.
getInstance
().
reportFree
(
BufferWriteProcessor
.
this
,
oldMemUsage
);
checkSize
();
};
FlushManager
.
getInstance
().
submit
(
flushThread
);
}
...
...
@@ -742,6 +769,10 @@ public class BufferWriteProcessor extends Processor {
flushingRowGroupWriters
=
null
;
flushingRecordCount
=
-
1
;
}
public
long
calculateMemSizeForAllGroup
(){
return
super
.
calculateMemSizeForAllGroup
();
}
}
private
void
switchIndexFromWorkToFlush
()
{
...
...
@@ -752,4 +783,44 @@ public class BufferWriteProcessor extends Processor {
bufferIOWriter
.
addNewRowGroupMetaDataToBackUp
();
}
}
/**
* @return The sum of all timeseries's metadata size within this file.
*/
public
long
getMetaSize
()
{
// TODO : [MemControl] implement this
return
0
;
}
/**
* @return The file size of the TsFile corresponding to this processor.
*/
public
long
getFileSize
()
{
// TODO : save this variable to avoid object creation?
File
file
=
new
File
(
bufferwriteOutputFilePath
);
return
file
.
length
();
}
/**
* Close current TsFile and open a new one for future writes.
* Block new writes and wait until current writes finish.
*/
public
void
rollToNewFile
()
{
// TODO : [MemControl] implement this
}
/**
* Check if this TsFile has too big metadata or file.
* If true, close current file and open a new one.
*/
private
void
checkSize
()
{
TsfileDBConfig
config
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
long
metaSize
=
getMetaSize
();
long
fileSize
=
getFileSize
();
if
(
metaSize
>=
config
.
bufferwriteMetaSizeThreshold
||
fileSize
>=
config
.
bufferwriteFileSizeThreshold
)
{
LOGGER
.
info
(
"{} size reaches threshold, closing. meta size is {}, file size is {}"
,
this
.
fileName
,
MemUtils
.
bytesCntToStr
(
metaSize
),
MemUtils
.
bytesCntToStr
(
fileSize
));
rollToNewFile
();
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/filenode/FileNodeManager.java
浏览文件 @
8445b08c
...
...
@@ -3,6 +3,10 @@ package cn.edu.tsinghua.iotdb.engine.filenode;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Iterator
;
...
...
@@ -26,6 +30,8 @@ import cn.edu.tsinghua.iotdb.engine.Processor;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.Action
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.BufferWriteProcessor
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.FileNodeConstants
;
import
cn.edu.tsinghua.iotdb.engine.flushthread.FlushManager
;
import
cn.edu.tsinghua.iotdb.engine.memcontrol.BasicMemController
;
import
cn.edu.tsinghua.iotdb.engine.overflow.io.OverflowProcessor
;
import
cn.edu.tsinghua.iotdb.exception.BufferWriteProcessorException
;
import
cn.edu.tsinghua.iotdb.exception.ErrorDebugException
;
...
...
@@ -163,6 +169,7 @@ public class FileNodeManager implements IStatistic {
public
synchronized
void
resetFileNodeManager
()
{
this
.
backUpOverflowedFileNodeName
=
new
HashSet
<>();
this
.
overflowedFileNodeName
=
new
HashSet
<>();
for
(
String
key:
statParamsHashMap
.
keySet
()){
statParamsHashMap
.
put
(
key
,
new
AtomicLong
());
}
...
...
@@ -267,6 +274,7 @@ public class FileNodeManager implements IStatistic {
FileNodeProcessor
fileNodeProcessor
=
getProcessor
(
deltaObjectId
,
true
);
int
insertType
=
0
;
try
{
long
lastUpdateTime
=
fileNodeProcessor
.
getLastUpdateTime
(
deltaObjectId
);
String
filenodeName
=
fileNodeProcessor
.
getProcessorName
();
...
...
@@ -952,4 +960,76 @@ public class FileNodeManager implements IStatistic {
private
enum
FileNodeManagerStatus
{
NONE
,
MERGE
,
CLOSE
;
}
public
void
forceFlush
(
BasicMemController
.
UsageLevel
level
)
{
// TODO : for each FileNodeProcessor, call its forceFlush()
// you may add some delicate process like below
// or you could provide multiple methods for different urgency
switch
(
level
)
{
case
WARNING:
// only select the most urgent (most active or biggest in size)
// processors to flush
// only select top 10% active memory user to flush
try
{
flushTop
(
0.1f
);
}
catch
(
IOException
e
)
{
LOGGER
.
error
(
"force flush memory data error"
,
e
.
getMessage
());
e
.
printStackTrace
();
}
break
;
case
DANGEROUS:
// force all processors to flush
try
{
flushAll
();
}
catch
(
IOException
e
)
{
LOGGER
.
error
(
"force flush memory data error:{}"
,
e
.
getMessage
());
e
.
printStackTrace
();
}
break
;
case
SAFE:
// if the flush thread pool is not full ( or half full), start a new
// flush task
if
(
FlushManager
.
getInstance
().
getActiveCnt
()
<
0.5
*
FlushManager
.
getInstance
().
getThreadCnt
())
{
try
{
flushTop
(
0.01f
);
}
catch
(
IOException
e
)
{
LOGGER
.
error
(
"force flush memory data error:{}"
,
e
.
getMessage
());
e
.
printStackTrace
();
}
}
break
;
}
}
private
void
flushAll
()
throws
IOException
{
for
(
FileNodeProcessor
processor
:
processorMap
.
values
())
{
processor
.
tryLock
(
true
);
try
{
processor
.
flush
();
}
finally
{
processor
.
unlock
(
true
);
}
}
}
private
void
flushTop
(
float
percentage
)
throws
IOException
{
List
<
FileNodeProcessor
>
tempProcessors
=
new
ArrayList
<>(
processorMap
.
values
());
// sort the tempProcessors as descending order
Collections
.
sort
(
tempProcessors
,
new
Comparator
<
FileNodeProcessor
>()
{
@Override
public
int
compare
(
FileNodeProcessor
o1
,
FileNodeProcessor
o2
)
{
return
(
int
)
(
o2
.
memoryUsage
()
-
o1
.
memoryUsage
());
}
});
int
flushNum
=
(
int
)
(
tempProcessors
.
size
()
*
percentage
)
>
1
?
(
int
)
(
tempProcessors
.
size
()
*
percentage
)
:
1
;
for
(
int
i
=
0
;
i
<
flushNum
&&
i
<
tempProcessors
.
size
();
i
++)
{
FileNodeProcessor
processor
=
tempProcessors
.
get
(
i
);
processor
.
writeLock
();
try
{
processor
.
flush
();
}
finally
{
processor
.
writeUnlock
();
}
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/filenode/FileNodeProcessor.java
浏览文件 @
8445b08c
...
...
@@ -1261,6 +1261,16 @@ public class FileNodeProcessor extends Processor implements IStatistic{
}
return
false
;
}
@Override
public
void
flush
()
throws
IOException
{
if
(
bufferWriteProcessor
!=
null
){
bufferWriteProcessor
.
flush
();
}
if
(
overflowProcessor
!=
null
){
overflowProcessor
.
flush
();
}
}
@Override
public
void
close
()
throws
FileNodeProcessorException
{
...
...
@@ -1330,6 +1340,18 @@ public class FileNodeProcessor extends Processor implements IStatistic{
}
}
}
@Override
public
long
memoryUsage
(){
long
memSize
=
0
;
if
(
bufferWriteProcessor
!=
null
){
memSize
+=
bufferWriteProcessor
.
memoryUsage
();
}
if
(
overflowProcessor
!=
null
){
memSize
+=
overflowProcessor
.
memoryUsage
();
}
return
memSize
;
}
private
void
writeStoreToDisk
(
FileNodeProcessorStore
fileNodeProcessorStore
)
throws
FileNodeProcessorException
{
...
...
src/main/java/cn/edu/tsinghua/iotdb/engine/flushthread/FlushManager.java
浏览文件 @
8445b08c
...
...
@@ -7,6 +7,7 @@ import cn.edu.tsinghua.tsfile.common.exception.ProcessorException;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
public
class
FlushManager
{
...
...
@@ -14,6 +15,7 @@ public class FlushManager {
private
static
final
int
EXIT_WAIT_TIME
=
60
*
1000
;
private
ExecutorService
pool
;
private
int
threadCnt
;
private
static
class
InstanceHolder
{
private
static
FlushManager
instance
=
new
FlushManager
();
...
...
@@ -21,7 +23,8 @@ public class FlushManager {
private
FlushManager
()
{
TsfileDBConfig
config
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
pool
=
IoTDBThreadPoolFactory
.
newFixedThreadPool
(
config
.
concurrentFlushThread
,
"Flush"
);
this
.
threadCnt
=
config
.
concurrentFlushThread
;
pool
=
IoTDBThreadPoolFactory
.
newFixedThreadPool
(
threadCnt
,
"Flush"
);
}
static
public
FlushManager
getInstance
(){
...
...
@@ -78,4 +81,11 @@ public class FlushManager {
pool
.
execute
(
task
);
}
public
int
getActiveCnt
()
{
return
((
ThreadPoolExecutor
)
pool
).
getActiveCount
();
}
public
int
getThreadCnt
()
{
return
threadCnt
;
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/BasicMemController.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
public
abstract
class
BasicMemController
{
public
enum
CONTROLLER_TYPE
{
RECORD
,
JVM
}
protected
long
warningThreshold
;
protected
long
dangerouseThreshold
;
protected
MemMonitorThread
monitorThread
;
protected
MemStatisticThread
memStatisticThread
;
public
enum
UsageLevel
{
SAFE
,
WARNING
,
DANGEROUS
}
BasicMemController
(
TsfileDBConfig
config
)
{
warningThreshold
=
config
.
memThresholdWarning
;
dangerouseThreshold
=
config
.
memThresholdDangerous
;
monitorThread
=
new
MemMonitorThread
(
config
.
memMonitorInterval
);
monitorThread
.
start
();
memStatisticThread
=
new
MemStatisticThread
();
memStatisticThread
.
start
();
}
// change instance here
public
static
BasicMemController
getInstance
()
{
switch
(
CONTROLLER_TYPE
.
values
()[
TsfileDBDescriptor
.
getInstance
().
getConfig
().
memControllerType
])
{
case
JVM:
return
JVMMemController
.
getInstance
();
case
RECORD:
default
:
return
RecordMemController
.
getInstance
();
}
}
public
void
setDangerouseThreshold
(
long
dangerouseThreshold
)
{
this
.
dangerouseThreshold
=
dangerouseThreshold
;
}
public
void
setWarningThreshold
(
long
warningThreshold
)
{
this
.
warningThreshold
=
warningThreshold
;
}
public
void
setCheckInterval
(
long
checkInterval
)
{
this
.
monitorThread
.
setCheckInterval
(
checkInterval
);
}
public
abstract
long
getTotalUsage
();
public
abstract
UsageLevel
getCurrLevel
();
public
abstract
void
clear
();
public
void
close
()
{
monitorThread
.
interrupt
();
memStatisticThread
.
interrupt
();
}
public
abstract
UsageLevel
reportUse
(
Object
user
,
long
usage
);
public
abstract
void
reportFree
(
Object
user
,
long
freeSize
);
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/FlushPartialPolicy.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.engine.filenode.FileNodeManager
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* This class only gives a hint to FilenodeManager that it may flush some data to avoid rush hour.
*/
public
class
FlushPartialPolicy
implements
Policy
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
FlushPartialPolicy
.
class
);
private
Thread
workerThread
;
@Override
public
void
execute
()
{
logger
.
info
(
"Memory reachs {}, current memory size {}, JVM memory {}, flushing."
,
BasicMemController
.
getInstance
().
getCurrLevel
(),
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()),
MemUtils
.
bytesCntToStr
(
Runtime
.
getRuntime
().
totalMemory
()
-
Runtime
.
getRuntime
().
freeMemory
()));
// use a thread to avoid blocking
if
(
workerThread
==
null
)
{
workerThread
=
new
Thread
(()
->
{
FileNodeManager
.
getInstance
().
forceFlush
(
BasicMemController
.
UsageLevel
.
SAFE
);
});
workerThread
.
start
();
}
else
{
if
(
workerThread
.
isAlive
())
{
logger
.
info
(
"Last flush is ongoing..."
);
}
else
{
workerThread
=
new
Thread
(()
->
{
FileNodeManager
.
getInstance
().
forceFlush
(
BasicMemController
.
UsageLevel
.
SAFE
);
});
workerThread
.
start
();
}
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/ForceFLushAllPolicy.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.engine.filenode.FileNodeManager
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
ForceFLushAllPolicy
implements
Policy
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
ForceFLushAllPolicy
.
class
);
private
Thread
workerThread
;
@Override
public
void
execute
()
{
logger
.
info
(
"Memory reachs {}, current memory size {}, JVM memory {}, flushing."
,
BasicMemController
.
getInstance
().
getCurrLevel
(),
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()),
MemUtils
.
bytesCntToStr
(
Runtime
.
getRuntime
().
totalMemory
()
-
Runtime
.
getRuntime
().
freeMemory
()));
// use a thread to avoid blocking
if
(
workerThread
==
null
)
{
workerThread
=
new
Thread
(()
->
{
FileNodeManager
.
getInstance
().
forceFlush
(
BasicMemController
.
UsageLevel
.
DANGEROUS
);
System
.
gc
();
});
workerThread
.
start
();
}
else
{
if
(
workerThread
.
isAlive
())
{
logger
.
info
(
"Last flush is ongoing..."
);
}
else
{
workerThread
=
new
Thread
(()
->
{
FileNodeManager
.
getInstance
().
forceFlush
(
BasicMemController
.
UsageLevel
.
DANGEROUS
);
System
.
gc
();
});
workerThread
.
start
();
}
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/JVMMemController.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
JVMMemController
extends
BasicMemController
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
JVMMemController
.
class
);
// memory used by non-data objects, this is used to estimate the memory used by data
private
long
nonDataUsage
=
0
;
private
static
class
InstanceHolder
{
private
static
final
JVMMemController
INSTANCE
=
new
JVMMemController
(
TsfileDBDescriptor
.
getInstance
().
getConfig
());
}
public
static
JVMMemController
getInstance
()
{
return
InstanceHolder
.
INSTANCE
;
}
private
JVMMemController
(
TsfileDBConfig
config
)
{
super
(
config
);
}
@Override
public
long
getTotalUsage
()
{
return
Runtime
.
getRuntime
().
totalMemory
()
-
Runtime
.
getRuntime
().
freeMemory
()
-
nonDataUsage
;
}
@Override
public
UsageLevel
getCurrLevel
()
{
long
memUsage
=
getTotalUsage
();
if
(
memUsage
<
warningThreshold
)
{
return
UsageLevel
.
SAFE
;
}
else
if
(
memUsage
<
dangerouseThreshold
)
{
return
UsageLevel
.
WARNING
;
}
else
{
return
UsageLevel
.
DANGEROUS
;
}
}
@Override
public
void
clear
()
{
}
@Override
public
void
close
()
{
super
.
close
();
}
@Override
public
UsageLevel
reportUse
(
Object
user
,
long
usage
)
{
long
memUsage
=
getTotalUsage
()
+
usage
;
if
(
memUsage
<
warningThreshold
)
{
/* logger.debug("Safe Threshold : {} allocated to {}, total usage {}",
MemUtils.bytesCntToStr(usage),
user.getClass(),
MemUtils.bytesCntToStr(memUsage));*/
return
UsageLevel
.
SAFE
;
}
else
if
(
memUsage
<
dangerouseThreshold
)
{
logger
.
debug
(
"Warning Threshold : {} allocated to {}, total usage {}"
,
MemUtils
.
bytesCntToStr
(
usage
),
user
.
getClass
(),
MemUtils
.
bytesCntToStr
(
memUsage
));
return
UsageLevel
.
WARNING
;
}
else
{
logger
.
warn
(
"Memory request from {} is denied, memory usage : {}"
,
user
.
getClass
(),
MemUtils
.
bytesCntToStr
(
memUsage
));
return
UsageLevel
.
DANGEROUS
;
}
}
@Override
public
void
reportFree
(
Object
user
,
long
freeSize
)
{
logger
.
info
(
"{} freed from {}, total usage {}"
,
MemUtils
.
bytesCntToStr
(
freeSize
)
,
user
.
getClass
()
,
MemUtils
.
bytesCntToStr
(
getTotalUsage
()));
System
.
gc
();
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemMonitorThread.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.engine.filenode.FileNodeManager
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
MemMonitorThread
extends
Thread
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
MemMonitorThread
.
class
);
private
long
checkInterval
=
1000
;
// in ms
private
Policy
safePolicy
;
private
Policy
warningPolicy
;
private
Policy
dangerousPolicy
;
public
MemMonitorThread
(
long
checkInterval
)
{
this
.
checkInterval
=
checkInterval
>
0
?
checkInterval
:
this
.
checkInterval
;
this
.
safePolicy
=
new
FlushPartialPolicy
();
this
.
warningPolicy
=
new
ForceFLushAllPolicy
();
this
.
dangerousPolicy
=
new
ForceFLushAllPolicy
();
}
public
void
setCheckInterval
(
long
checkInterval
)
{
this
.
checkInterval
=
checkInterval
;
}
@Override
public
void
run
()
{
logger
.
info
(
"MemMonitorThread started"
);
super
.
run
();
while
(
true
)
{
if
(
this
.
isInterrupted
())
{
logger
.
info
(
"MemMonitorThread exiting..."
);
return
;
}
BasicMemController
.
UsageLevel
level
=
BasicMemController
.
getInstance
().
getCurrLevel
();
switch
(
level
)
{
case
WARNING:
warningPolicy
.
execute
();
break
;
case
DANGEROUS:
dangerousPolicy
.
execute
();
break
;
case
SAFE:
safePolicy
.
execute
();
break
;
default
:
logger
.
error
(
"Unknown usage level : {}"
,
level
);
}
try
{
Thread
.
sleep
(
checkInterval
);
}
catch
(
InterruptedException
e
)
{
logger
.
info
(
"MemMonitorThread exiting..."
);
return
;
}
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemStatisticThread.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
MemStatisticThread
extends
Thread
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
MemStatisticThread
.
class
);
// update statistic every such interval
private
long
checkInterval
=
100
;
// in ms
private
long
minMemUsage
=
Long
.
MAX_VALUE
;
private
long
maxMemUsage
=
Long
.
MIN_VALUE
;
private
double
meanMemUsage
=
0.0
;
private
long
minJVMUsage
=
Long
.
MAX_VALUE
;
private
long
maxJVMUsage
=
Long
.
MIN_VALUE
;
private
double
meanJVMUsage
=
0.0
;
private
int
cnt
=
0
;
// log statistic every so many intervals
private
int
reportCycle
=
60
;
@Override
public
void
run
()
{
logger
.
info
(
"MemStatisticThread started"
);
try
{
// wait 3 mins for system to setup
Thread
.
sleep
(
3
*
60
*
1000
);
}
catch
(
InterruptedException
e
)
{
logger
.
info
(
"MemStatisticThread exiting..."
);
return
;
}
super
.
run
();
while
(
true
)
{
if
(
this
.
isInterrupted
())
{
logger
.
info
(
"MemStatisticThread exiting..."
);
return
;
}
long
memUsage
=
BasicMemController
.
getInstance
().
getTotalUsage
();
long
jvmUsage
=
Runtime
.
getRuntime
().
totalMemory
()
-
Runtime
.
getRuntime
().
freeMemory
();
minMemUsage
=
memUsage
<
minMemUsage
?
memUsage
:
minMemUsage
;
minJVMUsage
=
jvmUsage
<
minJVMUsage
?
jvmUsage
:
minJVMUsage
;
maxMemUsage
=
memUsage
>
maxMemUsage
?
memUsage
:
maxMemUsage
;
maxJVMUsage
=
jvmUsage
>
maxJVMUsage
?
jvmUsage
:
maxJVMUsage
;
double
doubleCnt
=
new
Integer
(
cnt
).
doubleValue
();
meanMemUsage
=
meanMemUsage
*
(
doubleCnt
/
(
doubleCnt
+
1.0
))
+
memUsage
/
(
doubleCnt
+
1.0
);
meanJVMUsage
=
meanJVMUsage
*
(
doubleCnt
/
(
doubleCnt
+
1.0
))
+
jvmUsage
/
(
doubleCnt
+
1.0
);
if
(++
cnt
%
reportCycle
==
0
)
logger
.
info
(
"Monitored memory usage, min {}, max {}, mean {} \n"
+
"JVM memory usage, min {}, max {}, mean {}"
,
MemUtils
.
bytesCntToStr
(
minMemUsage
),
MemUtils
.
bytesCntToStr
(
maxMemUsage
),
MemUtils
.
bytesCntToStr
(
new
Double
(
meanMemUsage
).
longValue
()),
MemUtils
.
bytesCntToStr
(
minJVMUsage
),
MemUtils
.
bytesCntToStr
(
maxJVMUsage
),
MemUtils
.
bytesCntToStr
(
new
Double
(
meanJVMUsage
).
longValue
()));
try
{
Thread
.
sleep
(
checkInterval
);
}
catch
(
InterruptedException
e
)
{
logger
.
info
(
"MemMonitorThread exiting..."
);
return
;
}
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/NoActPolicy.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
NoActPolicy
implements
Policy
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
NoActPolicy
.
class
);
@Override
public
void
execute
()
{
logger
.
info
(
"Memory check is safe, current usage {}, JVM memory {}"
,
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()),
MemUtils
.
bytesCntToStr
(
Runtime
.
getRuntime
().
totalMemory
()
-
Runtime
.
getRuntime
().
freeMemory
()));
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/Policy.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
/**
* This class defines what act will be taken if memory reach a certain threshold.
*/
public
interface
Policy
{
void
execute
();
}
src/main/java/cn/edu/tsinghua/iotdb/engine/memcontrol/RecordMemController.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicLong
;
/**
* This class hold global memory usage of MemUsers. This only counts record(tuple) sizes.
*/
public
class
RecordMemController
extends
BasicMemController
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
RecordMemController
.
class
);
// the key is the reference of the memory user, while the value is its memory usage in byte
private
Map
<
Object
,
Long
>
memMap
;
private
AtomicLong
totalMemUsed
;
private
static
class
InstanceHolder
{
private
static
final
RecordMemController
INSTANCE
=
new
RecordMemController
(
TsfileDBDescriptor
.
getInstance
().
getConfig
());
}
private
RecordMemController
(
TsfileDBConfig
config
)
{
super
(
config
);
memMap
=
new
HashMap
<>();
totalMemUsed
=
new
AtomicLong
(
0
);
}
public
static
RecordMemController
getInstance
()
{
return
InstanceHolder
.
INSTANCE
;
}
public
long
getTotalUsage
()
{
return
totalMemUsed
.
get
();
}
public
void
clear
()
{
memMap
.
clear
();
totalMemUsed
.
set
(
0
);
}
public
void
close
()
{
super
.
close
();
}
public
UsageLevel
getCurrLevel
()
{
long
memUsage
=
totalMemUsed
.
get
();
if
(
memUsage
<
warningThreshold
)
{
return
UsageLevel
.
SAFE
;
}
else
if
(
memUsage
<
dangerouseThreshold
)
{
return
UsageLevel
.
WARNING
;
}
else
{
return
UsageLevel
.
DANGEROUS
;
}
}
public
UsageLevel
reportUse
(
Object
user
,
long
usage
)
{
Long
oldUsage
=
memMap
.
get
(
user
);
if
(
oldUsage
==
null
)
oldUsage
=
0L
;
long
newTotUsage
=
totalMemUsed
.
get
()
+
usage
;
// check if the new usage will reach dangerous threshold
if
(
newTotUsage
<
dangerouseThreshold
)
{
newTotUsage
=
totalMemUsed
.
addAndGet
(
usage
);
// double check if updating will reach dangerous threshold
if
(
newTotUsage
<
warningThreshold
)
{
// still safe, action taken
memMap
.
put
(
user
,
oldUsage
+
usage
);
logger
.
debug
(
"Safe Threshold : {} allocated to {}, it is using {}, total usage {}"
,
MemUtils
.
bytesCntToStr
(
usage
),
user
.
getClass
(),
MemUtils
.
bytesCntToStr
(
oldUsage
+
usage
),
MemUtils
.
bytesCntToStr
(
newTotUsage
));
return
UsageLevel
.
SAFE
;
}
else
if
(
newTotUsage
<
dangerouseThreshold
)
{
// become warning because competition with other threads, still take the action
memMap
.
put
(
user
,
oldUsage
+
usage
);
logger
.
debug
(
"Warning Threshold : {} allocated to {}, it is using {}, total usage {}"
,
MemUtils
.
bytesCntToStr
(
usage
),
user
.
getClass
(),
MemUtils
.
bytesCntToStr
(
oldUsage
+
usage
),
MemUtils
.
bytesCntToStr
(
newTotUsage
));
return
UsageLevel
.
WARNING
;
}
else
{
logger
.
warn
(
"Memory request from {} is denied, memory usage : {}"
,
user
.
getClass
(),
MemUtils
.
bytesCntToStr
(
newTotUsage
));
// become dangerous because competition with other threads, discard this action
totalMemUsed
.
addAndGet
(-
usage
);
return
UsageLevel
.
DANGEROUS
;
}
}
else
{
logger
.
warn
(
"Memory request from {} is denied, memory usage : {}"
,
user
.
getClass
(),
MemUtils
.
bytesCntToStr
(
newTotUsage
));
return
UsageLevel
.
DANGEROUS
;
}
}
public
void
reportFree
(
Object
user
,
long
freeSize
)
{
Long
usage
=
memMap
.
get
(
user
);
if
(
usage
==
null
)
logger
.
error
(
"Unregistered memory usage from {}"
,
user
.
getClass
());
else
if
(
freeSize
>
usage
)
{
logger
.
error
(
"Request to free {} bytes while it only registered {} bytes"
,
freeSize
,
usage
);
totalMemUsed
.
addAndGet
(-
usage
);
memMap
.
put
(
user
,
0L
);
}
else
{
long
newTotalMemUsage
=
totalMemUsed
.
addAndGet
(-
freeSize
);
memMap
.
put
(
user
,
usage
-
freeSize
);
logger
.
info
(
"{} freed from {}, it is using {}, total usage {}"
,
MemUtils
.
bytesCntToStr
(
freeSize
)
,
user
.
getClass
()
,
MemUtils
.
bytesCntToStr
(
usage
-
freeSize
)
,
MemUtils
.
bytesCntToStr
(
newTotalMemUsage
));
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/engine/overflow/io/OverflowProcessor.java
浏览文件 @
8445b08c
...
...
@@ -8,6 +8,11 @@ import java.io.IOException;
import
java.util.List
;
import
java.util.Map
;
import
cn.edu.tsinghua.iotdb.engine.memcontrol.BasicMemController
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.DataPoint
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.TSRecord
;
import
cn.edu.tsinghua.iotdb.engine.flushthread.FlushManager
;
import
org.joda.time.DateTime
;
...
...
@@ -41,6 +46,7 @@ public class OverflowProcessor extends Processor {
private
static
final
int
MAXIMUM_RECORD_COUNT_FOR_CHECK
=
10000
;
private
long
recordCount
=
0
;
private
long
recordCountForNextMemCheck
=
MINIMUM_RECORD_COUNT_FOR_CHECK
;
private
long
memUsed
=
0
;
private
OverflowSupport
ofSupport
;
private
final
int
memoryBlockSize
=
TSFileDescriptor
.
getInstance
().
getConfig
().
groupSizeInByte
;
...
...
@@ -275,6 +281,35 @@ public class OverflowProcessor extends Processor {
insert
(
deltaObjectId
,
measurementId
,
timestamp
,
type
,
convertStringToBytes
(
type
,
v
));
}
// to unify with Methods in BufferWriteProcessor
public
void
insert
(
String
deltaObjectId
,
TSRecord
record
)
throws
OverflowProcessorException
{
long
newUsage
=
memUsed
;
BasicMemController
.
UsageLevel
level
=
BasicMemController
.
getInstance
().
reportUse
(
this
,
newUsage
);
switch
(
level
)
{
case
SAFE:
for
(
DataPoint
dataPoint
:
record
.
dataPointList
)
{
insert
(
deltaObjectId
,
dataPoint
.
getMeasurementId
(),
record
.
time
,
dataPoint
.
getType
(),
dataPoint
.
getValue
().
toString
());
}
memUsed
+=
newUsage
;
break
;
case
WARNING:
LOGGER
.
debug
(
"Memory usage will exceed warning threshold, current : {}."
,
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()));
for
(
DataPoint
dataPoint
:
record
.
dataPointList
)
{
insert
(
deltaObjectId
,
dataPoint
.
getMeasurementId
(),
record
.
time
,
dataPoint
.
getType
(),
dataPoint
.
getValue
().
toString
());
}
memUsed
+=
newUsage
;
break
;
case
DANGEROUS:
LOGGER
.
warn
(
"Memory usage will exceed dangerous threshold, current : {}."
,
MemUtils
.
bytesCntToStr
(
BasicMemController
.
getInstance
().
getTotalUsage
()));
throw
new
OverflowProcessorException
(
"Memory usage exceeded dangerous threshold."
);
default
:
}
}
private
void
insert
(
String
deltaObjectId
,
String
measurementId
,
long
timestamp
,
TSDataType
type
,
byte
[]
v
)
throws
OverflowProcessorException
{
if
(
ofSupport
.
insert
(
deltaObjectId
,
measurementId
,
timestamp
,
type
,
v
))
{
...
...
@@ -384,7 +419,8 @@ public class OverflowProcessor extends Processor {
}
}
}
long
oldMemUsage
=
memUsed
;
memUsed
=
0
;
if
(
TsfileDBDescriptor
.
getInstance
().
getConfig
().
enableWal
)
{
try
{
WriteLogManager
.
getInstance
().
startOverflowFlush
(
getProcessorName
());
...
...
@@ -438,6 +474,8 @@ public class OverflowProcessor extends Processor {
flushState
.
notify
();
}
}
BasicMemController
.
getInstance
().
reportFree
(
this
,
oldMemUsage
);
checkSize
();
}
else
{
// flush overflow row group asynchronously
flushState
.
setFlushing
();
...
...
@@ -468,6 +506,8 @@ public class OverflowProcessor extends Processor {
flushState
.
setUnFlushing
();
flushState
.
notify
();
}
BasicMemController
.
getInstance
().
reportFree
(
this
,
oldMemUsage
);
checkSize
();
}
};
FlushManager
.
getInstance
().
submit
(
AsynflushThread
);
...
...
@@ -484,6 +524,16 @@ public class OverflowProcessor extends Processor {
return
!
isMerging
&&
!
flushState
.
isFlushing
();
}
@Override
public
void
flush
()
throws
IOException
{
try
{
flushRowGroupToStore
(
false
);
}
catch
(
OverflowProcessorException
e
)
{
e
.
printStackTrace
();
throw
new
IOException
(
e
);
}
}
@Override
public
void
close
()
throws
OverflowProcessorException
{
LOGGER
.
info
(
"Start to close overflow processor, the overflow is {}"
,
getProcessorName
());
...
...
@@ -506,6 +556,12 @@ public class OverflowProcessor extends Processor {
LOGGER
.
warn
(
"Close the overflow processor, but no overflow metadata was flush"
);
}
}
@Override
public
long
memoryUsage
(){
return
ofSupport
.
calculateMemSize
();
}
public
void
switchWorkingToMerge
()
throws
OverflowProcessorException
{
synchronized
(
flushState
)
{
...
...
@@ -575,4 +631,45 @@ public class OverflowProcessor extends Processor {
this
.
ofFileMetadata
=
ofFileMetadata
;
}
}
/**
* @return The sum of all timeseries's metadata size within this file.
*/
public
long
getMetaSize
()
{
// TODO : [MemControl] implement this
return
0
;
}
/**
* @return The file size of the OverflowFile corresponding to this processor.
*/
public
long
getFileSize
()
{
// TODO : save this variable to avoid object creation?
File
file
=
new
File
(
overflowOutputFilePath
);
return
file
.
length
();
}
/**
* Close current OverflowFile and open a new one for future writes.
* Block new writes and wait until current writes finish.
*/
public
void
rollToNewFile
()
{
// TODO : [MemControl] implement this
}
/**
* Check if this OverflowFile has too big metadata or file.
* If true, close current file and open a new one.
*/
private
void
checkSize
()
{
TsfileDBConfig
config
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
long
metaSize
=
getMetaSize
();
long
fileSize
=
getFileSize
();
if
(
metaSize
>=
config
.
bufferwriteMetaSizeThreshold
||
fileSize
>=
config
.
bufferwriteFileSizeThreshold
)
{
LOGGER
.
info
(
"{} size reaches threshold, closing. meta size is {}, file size is {}"
,
this
.
fileName
,
MemUtils
.
bytesCntToStr
(
metaSize
),
MemUtils
.
bytesCntToStr
(
fileSize
));
rollToNewFile
();
}
}
}
src/main/java/cn/edu/tsinghua/iotdb/utils/MemUtils.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.utils
;
import
cn.edu.tsinghua.iotdb.conf.TsFileDBConstant
;
import
cn.edu.tsinghua.tsfile.common.utils.Binary
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.DataPoint
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.TSRecord
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.datapoint.*
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
// Notice : methods in this class may not be accurate.
public
class
MemUtils
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
MemUtils
.
class
);
// TODO : move this down to TsFile ?
/**
* Calculate how much memory will be used if the given record is written to Bufferwrite.
* @param record
* @return
*/
public
static
long
getTsRecordMemBufferwrite
(
TSRecord
record
)
{
long
memUsed
=
8
;
// time
memUsed
+=
8
;
// deltaObjectId reference
memUsed
+=
getStringMem
(
record
.
deltaObjectId
);
for
(
DataPoint
dataPoint
:
record
.
dataPointList
)
{
memUsed
+=
8
;
// dataPoint reference
memUsed
+=
getDataPointMem
(
dataPoint
);
}
return
memUsed
;
}
/**
* Calculate how much memory will be used if the given record is written to Bufferwrite.
* @param record
* @return
*/
public
static
long
getTsRecordMemOverflow
(
TSRecord
record
)
{
return
getTsRecordMemBufferwrite
(
record
);
}
public
static
long
getStringMem
(
String
str
)
{
// wide char (2 bytes each) and 64B String overhead
return
str
.
length
()
*
2
+
64
;
}
// TODO : move this down to TsFile
public
static
long
getDataPointMem
(
DataPoint
dataPoint
)
{
// type reference
long
memUsed
=
8
;
// measurementId and its reference
memUsed
+=
getStringMem
(
dataPoint
.
getMeasurementId
());
memUsed
+=
8
;
if
(
dataPoint
instanceof
FloatDataPoint
)
{
memUsed
+=
4
;
}
else
if
(
dataPoint
instanceof
IntDataPoint
)
{
memUsed
+=
4
;
}
else
if
(
dataPoint
instanceof
BooleanDataPoint
)
{
memUsed
+=
1
;
}
else
if
(
dataPoint
instanceof
DoubleDataPoint
)
{
memUsed
+=
8
;
}
else
if
(
dataPoint
instanceof
LongDataPoint
)
{
memUsed
+=
8
;
}
else
if
(
dataPoint
instanceof
EnumDataPoint
)
{
memUsed
+=
4
;
}
else
if
(
dataPoint
instanceof
StringDataPoint
)
{
StringDataPoint
stringDataPoint
=
(
StringDataPoint
)
dataPoint
;
memUsed
+=
8
+
20
;
// array reference and array overhead
memUsed
+=
((
Binary
)
stringDataPoint
.
getValue
()).
values
.
length
;
// encoding string reference and its memory
memUsed
+=
8
;
memUsed
+=
getStringMem
(((
Binary
)
stringDataPoint
.
getValue
()).
getTextEncodingType
());
}
else
{
logger
.
error
(
"Unsupported data point type"
);
}
return
memUsed
;
}
public
static
String
bytesCntToStr
(
long
cnt
)
{
long
GBs
=
cnt
/
TsFileDBConstant
.
GB
;
cnt
=
cnt
%
TsFileDBConstant
.
GB
;
long
MBs
=
cnt
/
TsFileDBConstant
.
MB
;
cnt
=
cnt
%
TsFileDBConstant
.
MB
;
long
KBs
=
cnt
/
TsFileDBConstant
.
KB
;
cnt
=
cnt
%
TsFileDBConstant
.
KB
;
return
GBs
+
" GB "
+
MBs
+
" MB "
+
KBs
+
" KB "
+
cnt
+
" B"
;
}
}
src/test/java/cn/edu/tsinghua/iotdb/engine/ProcessorTest.java
浏览文件 @
8445b08c
...
...
@@ -3,6 +3,7 @@ package cn.edu.tsinghua.iotdb.engine;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
...
...
@@ -11,6 +12,8 @@ import cn.edu.tsinghua.iotdb.engine.Processor;
import
cn.edu.tsinghua.iotdb.utils.EnvironmentUtils
;
import
cn.edu.tsinghua.tsfile.common.exception.ProcessorException
;
import
java.io.IOException
;
/**
* @author liukun
*
...
...
@@ -33,6 +36,17 @@ public class ProcessorTest {
public
void
close
()
throws
ProcessorException
{
}
@Override
public
void
flush
()
throws
IOException
{
// TODO Auto-generated method stub
}
@Override
public
long
memoryUsage
(){
return
0
;
}
}
...
...
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/BufferwriteFileSizeControlTest.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.engine.MetadataManagerHelper
;
import
cn.edu.tsinghua.iotdb.engine.PathUtils
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.Action
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.BufferWriteProcessor
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.FileNodeConstants
;
import
cn.edu.tsinghua.iotdb.exception.BufferWriteProcessorException
;
import
cn.edu.tsinghua.iotdb.utils.EnvironmentUtils
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileConfig
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileDescriptor
;
import
cn.edu.tsinghua.tsfile.file.metadata.enums.TSDataType
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.io.File
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.*;
public
class
BufferwriteFileSizeControlTest
{
Action
bfflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
Action
bfcloseaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
Action
fnflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
BufferWriteProcessor
processor
=
null
;
String
nsp
=
"root.vehicle.d0"
;
String
nsp2
=
"root.vehicle.d1"
;
private
boolean
cachePageData
=
false
;
private
int
groupSizeInByte
;
private
int
pageCheckSizeThreshold
;
private
int
pageSizeInByte
;
private
int
maxStringLength
;
private
long
fileSizeThreshold
;
private
long
memMonitorInterval
;
private
TSFileConfig
TsFileConf
=
TSFileDescriptor
.
getInstance
().
getConfig
();
private
TsfileDBConfig
dbConfig
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
private
boolean
skip
=
!
false
;
@Before
public
void
setUp
()
throws
Exception
{
//origin value
cachePageData
=
TsFileConf
.
duplicateIncompletedPage
;
groupSizeInByte
=
TsFileConf
.
groupSizeInByte
;
pageCheckSizeThreshold
=
TsFileConf
.
pageCheckSizeThreshold
;
pageSizeInByte
=
TsFileConf
.
pageSizeInByte
;
maxStringLength
=
TsFileConf
.
maxStringLength
;
fileSizeThreshold
=
dbConfig
.
bufferwriteFileSizeThreshold
;
memMonitorInterval
=
dbConfig
.
memMonitorInterval
;
//new value
TsFileConf
.
duplicateIncompletedPage
=
true
;
TsFileConf
.
groupSizeInByte
=
200000
;
TsFileConf
.
pageCheckSizeThreshold
=
3
;
TsFileConf
.
pageSizeInByte
=
10000
;
TsFileConf
.
maxStringLength
=
2
;
dbConfig
.
bufferwriteFileSizeThreshold
=
5
*
1024
*
1024
;
BasicMemController
.
getInstance
().
setCheckInterval
(
600
*
1000
);
// init metadata
MetadataManagerHelper
.
initMetadata
();
}
@After
public
void
tearDown
()
throws
Exception
{
//recovery value
TsFileConf
.
duplicateIncompletedPage
=
cachePageData
;
TsFileConf
.
groupSizeInByte
=
groupSizeInByte
;
TsFileConf
.
pageCheckSizeThreshold
=
pageCheckSizeThreshold
;
TsFileConf
.
pageSizeInByte
=
pageSizeInByte
;
TsFileConf
.
maxStringLength
=
maxStringLength
;
dbConfig
.
bufferwriteFileSizeThreshold
=
fileSizeThreshold
;
BasicMemController
.
getInstance
().
setCheckInterval
(
memMonitorInterval
);
//clean environment
EnvironmentUtils
.
cleanEnv
();
}
@Test
public
void
test
()
throws
BufferWriteProcessorException
{
if
(
skip
)
return
;
String
filename
=
"bufferwritetest"
;
new
File
(
filename
).
delete
();
Map
<
String
,
Object
>
parameters
=
new
HashMap
<>();
parameters
.
put
(
FileNodeConstants
.
BUFFERWRITE_FLUSH_ACTION
,
bfflushaction
);
parameters
.
put
(
FileNodeConstants
.
BUFFERWRITE_CLOSE_ACTION
,
bfcloseaction
);
parameters
.
put
(
FileNodeConstants
.
FILENODE_PROCESSOR_FLUSH_ACTION
,
fnflushaction
);
try
{
processor
=
new
BufferWriteProcessor
(
nsp
,
filename
,
parameters
);
}
catch
(
BufferWriteProcessorException
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
File
nspdir
=
PathUtils
.
getBufferWriteDir
(
nsp
);
assertEquals
(
true
,
nspdir
.
isDirectory
());
for
(
int
i
=
0
;
i
<
1000000
;
i
++)
{
processor
.
write
(
nsp
,
"s1"
,
i
*
i
,
TSDataType
.
INT64
,
i
+
""
);
processor
.
write
(
nsp2
,
"s1"
,
i
*
i
,
TSDataType
.
INT64
,
i
+
""
);
if
(
i
%
100000
==
0
)
System
.
out
.
println
(
i
+
","
+
MemUtils
.
bytesCntToStr
(
processor
.
getFileSize
()));
}
// wait to flush end
try
{
Thread
.
sleep
(
3000
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
processor
.
close
();
assertTrue
(
processor
.
getFileSize
()
<
dbConfig
.
bufferwriteFileSizeThreshold
);
fail
(
"Method unimplemented"
);
}
}
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/BufferwriteMetaSizeControlTest.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.engine.MetadataManagerHelper
;
import
cn.edu.tsinghua.iotdb.engine.PathUtils
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.Action
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.BufferWriteProcessor
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.FileNodeConstants
;
import
cn.edu.tsinghua.iotdb.exception.BufferWriteProcessorException
;
import
cn.edu.tsinghua.iotdb.utils.EnvironmentUtils
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileConfig
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileDescriptor
;
import
cn.edu.tsinghua.tsfile.file.metadata.enums.TSDataType
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.io.File
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.*;
public
class
BufferwriteMetaSizeControlTest
{
Action
bfflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
Action
bfcloseaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
Action
fnflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
BufferWriteProcessor
processor
=
null
;
String
nsp
=
"root.vehicle.d0"
;
String
nsp2
=
"root.vehicle.d1"
;
private
boolean
cachePageData
=
false
;
private
int
groupSizeInByte
;
private
int
pageCheckSizeThreshold
;
private
int
pageSizeInByte
;
private
int
maxStringLength
;
private
long
metaSizeThreshold
;
private
long
memMonitorInterval
;
private
TSFileConfig
TsFileConf
=
TSFileDescriptor
.
getInstance
().
getConfig
();
private
TsfileDBConfig
dbConfig
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
private
boolean
skip
=
!
false
;
@Before
public
void
setUp
()
throws
Exception
{
//origin value
cachePageData
=
TsFileConf
.
duplicateIncompletedPage
;
groupSizeInByte
=
TsFileConf
.
groupSizeInByte
;
pageCheckSizeThreshold
=
TsFileConf
.
pageCheckSizeThreshold
;
pageSizeInByte
=
TsFileConf
.
pageSizeInByte
;
maxStringLength
=
TsFileConf
.
maxStringLength
;
metaSizeThreshold
=
dbConfig
.
bufferwriteFileSizeThreshold
;
memMonitorInterval
=
dbConfig
.
memMonitorInterval
;
//new value
TsFileConf
.
duplicateIncompletedPage
=
true
;
TsFileConf
.
groupSizeInByte
=
200000
;
TsFileConf
.
pageCheckSizeThreshold
=
3
;
TsFileConf
.
pageSizeInByte
=
10000
;
TsFileConf
.
maxStringLength
=
2
;
dbConfig
.
bufferwriteMetaSizeThreshold
=
1024
*
1024
;
BasicMemController
.
getInstance
().
setCheckInterval
(
600
*
1000
);
// init metadata
MetadataManagerHelper
.
initMetadata
();
}
@After
public
void
tearDown
()
throws
Exception
{
//recovery value
TsFileConf
.
duplicateIncompletedPage
=
cachePageData
;
TsFileConf
.
groupSizeInByte
=
groupSizeInByte
;
TsFileConf
.
pageCheckSizeThreshold
=
pageCheckSizeThreshold
;
TsFileConf
.
pageSizeInByte
=
pageSizeInByte
;
TsFileConf
.
maxStringLength
=
maxStringLength
;
dbConfig
.
bufferwriteMetaSizeThreshold
=
metaSizeThreshold
;
BasicMemController
.
getInstance
().
setCheckInterval
(
memMonitorInterval
);
//clean environment
EnvironmentUtils
.
cleanEnv
();
}
@Test
public
void
test
()
throws
BufferWriteProcessorException
{
if
(
skip
)
return
;
String
filename
=
"bufferwritetest"
;
new
File
(
filename
).
delete
();
Map
<
String
,
Object
>
parameters
=
new
HashMap
<>();
parameters
.
put
(
FileNodeConstants
.
BUFFERWRITE_FLUSH_ACTION
,
bfflushaction
);
parameters
.
put
(
FileNodeConstants
.
BUFFERWRITE_CLOSE_ACTION
,
bfcloseaction
);
parameters
.
put
(
FileNodeConstants
.
FILENODE_PROCESSOR_FLUSH_ACTION
,
fnflushaction
);
try
{
processor
=
new
BufferWriteProcessor
(
nsp
,
filename
,
parameters
);
}
catch
(
BufferWriteProcessorException
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
File
nspdir
=
PathUtils
.
getBufferWriteDir
(
nsp
);
assertEquals
(
true
,
nspdir
.
isDirectory
());
for
(
int
i
=
0
;
i
<
1000000
;
i
++)
{
processor
.
write
(
nsp
,
"s1"
,
i
*
i
,
TSDataType
.
INT64
,
i
+
""
);
processor
.
write
(
nsp2
,
"s1"
,
i
*
i
,
TSDataType
.
INT64
,
i
+
""
);
if
(
i
%
100000
==
0
)
System
.
out
.
println
(
i
+
","
+
MemUtils
.
bytesCntToStr
(
processor
.
getMetaSize
()));
}
// wait to flush end
try
{
Thread
.
sleep
(
3000
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
assertTrue
(
processor
.
getMetaSize
()
<
dbConfig
.
bufferwriteFileSizeThreshold
);
processor
.
close
();
fail
(
"Method unimplemented"
);
}
}
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemControlTest.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsFileDBConstant
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.jdbc.TsfileJDBCConfig
;
import
cn.edu.tsinghua.iotdb.service.IoTDB
;
import
cn.edu.tsinghua.iotdb.service.TestUtils
;
import
cn.edu.tsinghua.iotdb.utils.EnvironmentUtils
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.common.utils.Binary
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.TSRecord
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.datapoint.FloatDataPoint
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.datapoint.IntDataPoint
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.datapoint.LongDataPoint
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.datapoint.StringDataPoint
;
import
org.apache.commons.io.FileUtils
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.io.File
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
static
junit
.
framework
.
TestCase
.
assertEquals
;
public
class
MemControlTest
{
private
final
String
FOLDER_HEADER
=
"src/test/resources"
;
private
static
final
String
TIMESTAMP_STR
=
"Time"
;
private
final
String
d0
=
"root.vehicle.d0"
;
private
final
String
d1
=
"root.house.d0"
;
private
final
String
s0
=
"s0"
;
private
final
String
s1
=
"s1"
;
private
final
String
s2
=
"s2"
;
private
final
String
s3
=
"s3"
;
private
String
[]
sqls
=
new
String
[]{
"SET STORAGE GROUP TO root.vehicle"
,
"SET STORAGE GROUP TO root.house"
,
"CREATE TIMESERIES root.vehicle.d1.s0 WITH DATATYPE=INT32, ENCODING=RLE"
,
"CREATE TIMESERIES root.vehicle.d0.s2 WITH DATATYPE=FLOAT, ENCODING=RLE"
,
"CREATE TIMESERIES root.vehicle.d0.s3 WITH DATATYPE=TEXT, ENCODING=PLAIN"
,
"CREATE TIMESERIES root.vehicle.d0.s0 WITH DATATYPE=INT32, ENCODING=RLE"
,
"CREATE TIMESERIES root.vehicle.d0.s1 WITH DATATYPE=INT64, ENCODING=RLE"
,
"CREATE TIMESERIES root.vehicle.d0.s4 WITH DATATYPE=BOOLEAN, ENCODING=PLAIN"
,
"CREATE TIMESERIES root.house.d1.s0 WITH DATATYPE=INT32, ENCODING=RLE"
,
"CREATE TIMESERIES root.house.d0.s2 WITH DATATYPE=FLOAT, ENCODING=RLE"
,
"CREATE TIMESERIES root.house.d0.s3 WITH DATATYPE=TEXT, ENCODING=PLAIN"
,
"CREATE TIMESERIES root.house.d0.s0 WITH DATATYPE=INT32, ENCODING=RLE"
,
"CREATE TIMESERIES root.house.d0.s1 WITH DATATYPE=INT64, ENCODING=RLE"
,
"CREATE TIMESERIES root.house.d0.s4 WITH DATATYPE=BOOLEAN, ENCODING=PLAIN"
};
TsfileDBConfig
config
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
private
IoTDB
deamon
;
private
boolean
testFlag
=
false
;
private
boolean
exceptionCaught
=
false
;
public
MemControlTest
()
{
}
@Before
public
void
setUp
()
throws
Exception
{
if
(
testFlag
)
{
deamon
=
IoTDB
.
getInstance
();
EnvironmentUtils
.
envSetUp
();
config
.
memThresholdWarning
=
3
*
TsFileDBConstant
.
MB
;
config
.
memThresholdDangerous
=
5
*
TsFileDBConstant
.
MB
;
BasicMemController
.
getInstance
().
setCheckInterval
(
15
*
1000
);
BasicMemController
.
getInstance
().
setDangerouseThreshold
(
config
.
memThresholdDangerous
);
// force initialize
BasicMemController
.
getInstance
().
setWarningThreshold
(
config
.
memThresholdWarning
);
deamon
.
active
();
insertSQL
();
}
}
@After
public
void
tearDown
()
throws
Exception
{
if
(
testFlag
)
{
deamon
.
stop
();
Thread
.
sleep
(
5000
);
EnvironmentUtils
.
cleanEnv
();
}
}
@Test
public
void
test
()
throws
ClassNotFoundException
,
SQLException
,
InterruptedException
{
// test a huge amount of write causes block
if
(!
testFlag
)
return
;
Thread
t1
=
new
Thread
(()
->
insert
(
d0
));
Thread
t2
=
new
Thread
(()
->
insert
(
d1
));
t1
.
start
();
t2
.
start
();
t1
.
join
();
t2
.
join
();
assertEquals
(
exceptionCaught
,
true
);
assertEquals
(
BasicMemController
.
UsageLevel
.
WARNING
,
BasicMemController
.
getInstance
().
getCurrLevel
());
// test MemControlTread auto flush
Thread
.
sleep
(
15000
);
assertEquals
(
BasicMemController
.
UsageLevel
.
SAFE
,
BasicMemController
.
getInstance
().
getCurrLevel
());
}
public
void
insert
(
String
deviceId
)
{
try
{
Class
.
forName
(
TsfileJDBCConfig
.
JDBC_DRIVER_NAME
);
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
Connection
connection
=
null
;
TSRecord
record
=
new
TSRecord
(
0
,
deviceId
);
record
.
addTuple
(
new
IntDataPoint
(
s0
,
0
));
record
.
addTuple
(
new
LongDataPoint
(
s1
,
0
));
record
.
addTuple
(
new
FloatDataPoint
(
s2
,
0.0f
));
record
.
addTuple
(
new
StringDataPoint
(
s3
,
new
Binary
(
"\"sadasgagfdhdshdhdfhdfhdhdhdfherherdfsdfbdfsherhedfjerjerdfshfdshxzcvenerhreherjnfdgntrnt"
+
"ddfhdsf,joreinmoidnfh\""
)));
long
recordMemSize
=
MemUtils
.
getTsRecordMemBufferwrite
(
record
);
long
insertCnt
=
config
.
memThresholdDangerous
/
recordMemSize
*
2
;
System
.
out
.
println
(
Thread
.
currentThread
().
getId
()
+
" to insert "
+
insertCnt
);
try
{
connection
=
DriverManager
.
getConnection
(
"jdbc:tsfile://127.0.0.1:6667/"
,
"root"
,
"root"
);
Statement
statement
=
connection
.
createStatement
();
for
(
int
i
=
0
;
i
<
insertCnt
;
i
++)
{
record
.
time
=
i
+
1
;
statement
.
execute
(
TestUtils
.
recordToInsert
(
record
));
if
(
i
%
1000
==
0
)
{
System
.
out
.
println
(
Thread
.
currentThread
().
getId
()
+
" inserting "
+
i
);
}
}
statement
.
close
();
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
e
.
getMessage
());
if
(
e
.
getMessage
().
contains
(
"exceeded dangerous threshold"
))
exceptionCaught
=
true
;
}
finally
{
if
(
connection
!=
null
)
{
try
{
connection
.
close
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
}
}
}
private
void
insertSQL
()
throws
ClassNotFoundException
,
SQLException
{
Class
.
forName
(
TsfileJDBCConfig
.
JDBC_DRIVER_NAME
);
Connection
connection
=
null
;
try
{
connection
=
DriverManager
.
getConnection
(
"jdbc:tsfile://127.0.0.1:6667/"
,
"root"
,
"root"
);
Statement
statement
=
connection
.
createStatement
();
for
(
String
sql
:
sqls
)
{
statement
.
execute
(
sql
);
}
statement
.
close
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
if
(
connection
!=
null
)
{
connection
.
close
();
}
}
}
}
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/MemControllerTest.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.exception.BufferWriteProcessorException
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
public
class
MemControllerTest
{
private
TsfileDBConfig
config
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
private
static
long
GB
=
1024
*
1024
*
1024L
;
private
static
long
MB
=
1024
*
1024L
;
@Test
public
void
test
()
throws
BufferWriteProcessorException
{
BasicMemController
memController
=
BasicMemController
.
getInstance
();
if
(
memController
instanceof
RecordMemController
)
testRecordMemController
();
}
private
void
testRecordMemController
()
{
BasicMemController
memController
=
BasicMemController
.
getInstance
();
memController
.
clear
();
memController
.
setWarningThreshold
(
8
*
GB
);
memController
.
setDangerouseThreshold
(
16
*
GB
);
Object
[]
dummyUser
=
new
Object
[
20
];
for
(
int
i
=
0
;
i
<
dummyUser
.
length
;
i
++)
dummyUser
[
i
]
=
new
Object
();
// every one request 1 GB, should get 7 safes, 8 warning and 5 dangerous
for
(
int
i
=
0
;
i
<
7
;
i
++)
{
BasicMemController
.
UsageLevel
level
=
memController
.
reportUse
(
dummyUser
[
i
],
1
*
GB
);
assertEquals
(
BasicMemController
.
UsageLevel
.
SAFE
,
level
);
}
for
(
int
i
=
7
;
i
<
15
;
i
++)
{
BasicMemController
.
UsageLevel
level
=
memController
.
reportUse
(
dummyUser
[
i
],
1
*
GB
);
assertEquals
(
BasicMemController
.
UsageLevel
.
WARNING
,
level
);
}
for
(
int
i
=
15
;
i
<
20
;
i
++)
{
BasicMemController
.
UsageLevel
level
=
memController
.
reportUse
(
dummyUser
[
i
],
1
*
GB
);
assertEquals
(
BasicMemController
.
UsageLevel
.
DANGEROUS
,
level
);
}
assertEquals
(
15
*
GB
,
memController
.
getTotalUsage
());
// every one free its mem
for
(
int
i
=
0
;
i
<
7
;
i
++)
{
memController
.
reportFree
(
dummyUser
[
i
],
1
*
GB
);
assertEquals
((
14
-
i
)
*
GB
,
memController
.
getTotalUsage
());
}
for
(
int
i
=
7
;
i
<
15
;
i
++)
{
memController
.
reportFree
(
dummyUser
[
i
],
2
*
GB
);
assertEquals
((
14
-
i
)
*
GB
,
memController
.
getTotalUsage
());
}
// ask for a too big mem
BasicMemController
.
UsageLevel
level
=
memController
.
reportUse
(
dummyUser
[
0
],
100
*
GB
);
assertEquals
(
BasicMemController
.
UsageLevel
.
DANGEROUS
,
level
);
// single user ask continuously
for
(
int
i
=
0
;
i
<
8
*
1024
-
1
;
i
++)
{
level
=
memController
.
reportUse
(
dummyUser
[
0
],
1
*
MB
);
assertEquals
(
BasicMemController
.
UsageLevel
.
SAFE
,
level
);
}
for
(
int
i
=
8
*
1024
-
1
;
i
<
16
*
1024
-
1
;
i
++)
{
level
=
memController
.
reportUse
(
dummyUser
[
0
],
1
*
MB
);
assertEquals
(
BasicMemController
.
UsageLevel
.
WARNING
,
level
);
}
for
(
int
i
=
16
*
1024
-
1
;
i
<
17
*
1024
;
i
++)
{
level
=
memController
.
reportUse
(
dummyUser
[
0
],
1
*
MB
);
System
.
out
.
println
(
memController
.
getTotalUsage
()
/
GB
+
" "
+
memController
.
getTotalUsage
()
/
MB
%
1024
);
assertEquals
(
BasicMemController
.
UsageLevel
.
DANGEROUS
,
level
);
}
}
}
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/OverflowFileSizeControlTest.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.engine.MetadataManagerHelper
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.Action
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.FileNodeConstants
;
import
cn.edu.tsinghua.iotdb.engine.overflow.io.OverflowProcessor
;
import
cn.edu.tsinghua.iotdb.exception.OverflowProcessorException
;
import
cn.edu.tsinghua.iotdb.utils.EnvironmentUtils
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileConfig
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileDescriptor
;
import
cn.edu.tsinghua.tsfile.file.metadata.enums.TSDataType
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
public
class
OverflowFileSizeControlTest
{
private
String
nameSpacePath
=
"nsp"
;
private
Map
<
String
,
Object
>
parameters
=
null
;
private
OverflowProcessor
ofprocessor
=
null
;
private
TSFileConfig
tsconfig
=
TSFileDescriptor
.
getInstance
().
getConfig
();
private
String
deltaObjectId
=
"root.vehicle.d0"
;
private
String
[]
measurementIds
=
{
"s0"
,
"s1"
,
"s2"
,
"s3"
,
"s4"
,
"s5"
};
private
TSDataType
[]
dataTypes
=
{
TSDataType
.
INT32
,
TSDataType
.
INT64
,
TSDataType
.
FLOAT
,
TSDataType
.
DOUBLE
,
TSDataType
.
BOOLEAN
,
TSDataType
.
TEXT
};
private
TsfileDBConfig
dbConfig
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
private
long
overflowFileSize
;
private
int
groupSize
;
private
boolean
skip
=
!
false
;
private
Action
overflowflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
private
Action
filenodeflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
private
Action
filenodemanagerbackupaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
private
Action
filenodemanagerflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
@Before
public
void
setUp
()
throws
Exception
{
parameters
=
new
HashMap
<
String
,
Object
>();
parameters
.
put
(
FileNodeConstants
.
OVERFLOW_FLUSH_ACTION
,
overflowflushaction
);
parameters
.
put
(
FileNodeConstants
.
FILENODE_PROCESSOR_FLUSH_ACTION
,
filenodeflushaction
);
parameters
.
put
(
FileNodeConstants
.
OVERFLOW_BACKUP_MANAGER_ACTION
,
filenodemanagerbackupaction
);
parameters
.
put
(
FileNodeConstants
.
OVERFLOW_FLUSH_MANAGER_ACTION
,
filenodemanagerflushaction
);
overflowFileSize
=
dbConfig
.
overflowFileSizeThreshold
;
groupSize
=
tsconfig
.
groupSizeInByte
;
dbConfig
.
overflowFileSizeThreshold
=
10
*
1024
*
1024
;
tsconfig
.
groupSizeInByte
=
1024
*
1024
;
MetadataManagerHelper
.
initMetadata
();
}
@After
public
void
tearDown
()
throws
Exception
{
dbConfig
.
overflowFileSizeThreshold
=
overflowFileSize
;
tsconfig
.
groupSizeInByte
=
groupSize
;
EnvironmentUtils
.
cleanEnv
();
}
@Test
public
void
testInsert
()
throws
InterruptedException
{
if
(
skip
)
return
;
// insert one point: int
try
{
ofprocessor
=
new
OverflowProcessor
(
nameSpacePath
,
parameters
);
for
(
int
i
=
1
;
i
<
1000000
;
i
++)
{
ofprocessor
.
insert
(
deltaObjectId
,
measurementIds
[
0
],
i
,
dataTypes
[
0
],
Integer
.
toString
(
i
));
if
(
i
%
100000
==
0
)
System
.
out
.
println
(
i
+
","
+
MemUtils
.
bytesCntToStr
(
ofprocessor
.
getFileSize
()));
}
// wait to flush
Thread
.
sleep
(
1000
);
ofprocessor
.
close
();
assertTrue
(
ofprocessor
.
getFileSize
()
<
dbConfig
.
overflowFileSizeThreshold
);
fail
(
"Method unimplemented"
);
}
catch
(
OverflowProcessorException
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
}
}
src/test/java/cn/edu/tsinghua/iotdb/engine/memcontrol/OverflowMetaSizeControlTest.java
0 → 100644
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.engine.memcontrol
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBConfig
;
import
cn.edu.tsinghua.iotdb.conf.TsfileDBDescriptor
;
import
cn.edu.tsinghua.iotdb.engine.MetadataManagerHelper
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.Action
;
import
cn.edu.tsinghua.iotdb.engine.bufferwrite.FileNodeConstants
;
import
cn.edu.tsinghua.iotdb.engine.overflow.io.OverflowProcessor
;
import
cn.edu.tsinghua.iotdb.exception.OverflowProcessorException
;
import
cn.edu.tsinghua.iotdb.utils.EnvironmentUtils
;
import
cn.edu.tsinghua.iotdb.utils.MemUtils
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileConfig
;
import
cn.edu.tsinghua.tsfile.common.conf.TSFileDescriptor
;
import
cn.edu.tsinghua.tsfile.file.metadata.enums.TSDataType
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
public
class
OverflowMetaSizeControlTest
{
private
String
nameSpacePath
=
"nsp"
;
private
Map
<
String
,
Object
>
parameters
=
null
;
private
OverflowProcessor
ofprocessor
=
null
;
private
TSFileConfig
tsconfig
=
TSFileDescriptor
.
getInstance
().
getConfig
();
private
String
deltaObjectId
=
"root.vehicle.d0"
;
private
String
[]
measurementIds
=
{
"s0"
,
"s1"
,
"s2"
,
"s3"
,
"s4"
,
"s5"
};
private
TSDataType
[]
dataTypes
=
{
TSDataType
.
INT32
,
TSDataType
.
INT64
,
TSDataType
.
FLOAT
,
TSDataType
.
DOUBLE
,
TSDataType
.
BOOLEAN
,
TSDataType
.
TEXT
};
private
TsfileDBConfig
dbConfig
=
TsfileDBDescriptor
.
getInstance
().
getConfig
();
private
long
overflowFileSize
;
private
int
groupSize
;
private
boolean
skip
=
!
false
;
private
Action
overflowflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
private
Action
filenodeflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
private
Action
filenodemanagerbackupaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
private
Action
filenodemanagerflushaction
=
new
Action
()
{
@Override
public
void
act
()
throws
Exception
{
}
};
@Before
public
void
setUp
()
throws
Exception
{
parameters
=
new
HashMap
<
String
,
Object
>();
parameters
.
put
(
FileNodeConstants
.
OVERFLOW_FLUSH_ACTION
,
overflowflushaction
);
parameters
.
put
(
FileNodeConstants
.
FILENODE_PROCESSOR_FLUSH_ACTION
,
filenodeflushaction
);
parameters
.
put
(
FileNodeConstants
.
OVERFLOW_BACKUP_MANAGER_ACTION
,
filenodemanagerbackupaction
);
parameters
.
put
(
FileNodeConstants
.
OVERFLOW_FLUSH_MANAGER_ACTION
,
filenodemanagerflushaction
);
overflowFileSize
=
dbConfig
.
overflowMetaSizeThreshold
;
groupSize
=
tsconfig
.
groupSizeInByte
;
dbConfig
.
overflowMetaSizeThreshold
=
3
*
1024
*
1024
;
tsconfig
.
groupSizeInByte
=
1024
*
1024
;
MetadataManagerHelper
.
initMetadata
();
}
@After
public
void
tearDown
()
throws
Exception
{
dbConfig
.
overflowMetaSizeThreshold
=
overflowFileSize
;
tsconfig
.
groupSizeInByte
=
groupSize
;
EnvironmentUtils
.
cleanEnv
();
}
@Test
public
void
testInsert
()
throws
InterruptedException
{
if
(
skip
)
return
;
// insert one point: int
try
{
ofprocessor
=
new
OverflowProcessor
(
nameSpacePath
,
parameters
);
for
(
int
i
=
1
;
i
<
1000000
;
i
++)
{
ofprocessor
.
insert
(
deltaObjectId
,
measurementIds
[
0
],
i
,
dataTypes
[
0
],
Integer
.
toString
(
i
));
if
(
i
%
100000
==
0
)
System
.
out
.
println
(
i
+
","
+
MemUtils
.
bytesCntToStr
(
ofprocessor
.
getMetaSize
()));
}
// wait to flush
Thread
.
sleep
(
1000
);
assertTrue
(
ofprocessor
.
getMetaSize
()
<
dbConfig
.
overflowMetaSizeThreshold
);
ofprocessor
.
close
();
fail
(
"Method unimplemented"
);
}
catch
(
OverflowProcessorException
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
}
}
src/test/java/cn/edu/tsinghua/iotdb/service/LargeDataTest.java
浏览文件 @
8445b08c
...
...
@@ -109,16 +109,16 @@ public class LargeDataTest {
Connection
connection
=
DriverManager
.
getConnection
(
"jdbc:tsfile://127.0.0.1:6667/"
,
"root"
,
"root"
);
selectOneSeriesWithValueFilterTest
();
/*
selectOneSeriesWithValueFilterTest();
aggregationTest();
groupByTest();
allNullSeriesAggregationTest();
allNullSeriesGroupByTest
();
allNullSeriesGroupByTest();
*/
negativeValueTest
();
fixBigGroupByClassFormNumberTest
();
/*
fixBigGroupByClassFormNumberTest();
seriesTimeDigestTest();
...
...
@@ -126,7 +126,7 @@ public class LargeDataTest {
linearFillTest();
connection
.
close
();
connection.close();
*/
}
}
...
...
src/test/java/cn/edu/tsinghua/iotdb/service/TestUtils.java
浏览文件 @
8445b08c
package
cn.edu.tsinghua.iotdb.service
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.DataPoint
;
import
cn.edu.tsinghua.tsfile.timeseries.write.record.TSRecord
;
public
class
TestUtils
{
public
static
boolean
testFlag
=
true
;
public
static
String
insertTemplate
=
"insert into %s(timestamp%s) values(%d%s)"
;
public
static
String
first
(
String
path
)
{
return
String
.
format
(
"first(%s)"
,
path
);
}
...
...
@@ -18,6 +23,7 @@ public class TestUtils {
}
public
static
String
count
(
String
path
)
{
return
String
.
format
(
"count(%s)"
,
path
);
}
...
...
@@ -36,4 +42,14 @@ public class TestUtils {
public
static
String
min_value
(
String
path
)
{
return
String
.
format
(
"min_value(%s)"
,
path
);
}
public
static
String
recordToInsert
(
TSRecord
record
)
{
StringBuilder
measurements
=
new
StringBuilder
();
StringBuilder
values
=
new
StringBuilder
();
for
(
DataPoint
dataPoint
:
record
.
dataPointList
)
{
measurements
.
append
(
","
).
append
(
dataPoint
.
getMeasurementId
());
values
.
append
(
","
).
append
(
dataPoint
.
getValue
());
}
return
String
.
format
(
insertTemplate
,
record
.
deltaObjectId
,
measurements
.
toString
(),
record
.
time
,
values
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录