Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions python/README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,45 @@ mvn -P with-cpp,with-python clean verify
python setup.py build_ext --inplace
```

## Dataset 读取资源上限

`TsFileDataFrame` 在 `use_index=True` 时支持以下仅限关键字的配置参数:

```python
from tsfile import TsFileDataFrame

with TsFileDataFrame(
["part1.tsfile", "part2.tsfile"],
use_index=True,
max_prepared_series=32,
descriptor_cache_size=32,
max_open_files=16,
query_workers=4,
) as frame:
values = frame[0][:]
```

| 参数 | 环境变量 | 默认值 | 有效取值 |
|------|----------|--------|----------|
| `max_prepared_series` | `TSFILE_DATAFRAME_MAX_PREPARED_SERIES` | 4096 | 非负整数 |
| `descriptor_cache_size` | `TSFILE_DATAFRAME_DESCRIPTOR_CACHE_SIZE` | 4096 | 非负整数 |
| `max_open_files` | `TSFILE_DATAFRAME_MAX_OPEN_FILES` | 16 | 正整数 |
| `query_workers` | `TSFILE_DATAFRAME_QUERY_WORKERS` | `min(4, os.cpu_count() or 1)` | 正整数 |
| `query_parallel_min_rows` | `TSFILE_DATAFRAME_QUERY_PARALLEL_MIN_ROWS` | 8192 | 正整数 |

显式参数优先于对应的环境变量。参数为 `None` 时读取环境变量;变量未设置时
使用内置默认值。配置在构造 frame 时一次性确定,之后修改环境变量不会影响
已有 frame。子集共享父 frame 的 runtime 和配置。非法值在打开数据文件或索引前
报错。显式传入这些参数要求 `use_index=True`;默认的无索引模式不读取这些环境变量。

预备序列缓存保留已解析的原生序列元数据,按 LRU 淘汰空闲条目并释放原生句柄。
查询正在使用的条目,以及其他序列仍依赖的共享时间元数据,会保持有效,因而
并发查询期间条目数可能暂时超过上限,查询结束后再回收。这是每个 runtime 的
条目数量上限,不是整个进程的内存上限;设置为 `0` 表示使用结束后不保留缓存。
`descriptor_cache_size` 分别限制名称描述符缓存和序列路由缓存,`0` 禁用二者。
`max_open_files` 限制打开的 reader 数量,`query_workers=1` 表示串行执行查询组。
多个 runtime 或工作进程分别维护各自的上限。

## 文件级 Properties

`TsFileWriter` 和 `TsFileTableWriter` 可以在打开期间写入二进制 property。
Expand Down
44 changes: 44 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,50 @@ Build by python command:
python setup.py build_ext --inplace
```

## Dataset read resource limits

`TsFileDataFrame` accepts keyword-only resource options when `use_index=True`:

```python
from tsfile import TsFileDataFrame

with TsFileDataFrame(
["part1.tsfile", "part2.tsfile"],
use_index=True,
max_prepared_series=32,
descriptor_cache_size=32,
max_open_files=16,
query_workers=4,
) as frame:
values = frame[0][:]
```

| Parameter | Environment variable | Default | Allowed values |
|-----------|----------------------|---------|----------------|
| `max_prepared_series` | `TSFILE_DATAFRAME_MAX_PREPARED_SERIES` | 4096 | Integer >= 0 |
| `descriptor_cache_size` | `TSFILE_DATAFRAME_DESCRIPTOR_CACHE_SIZE` | 4096 | Integer >= 0 |
| `max_open_files` | `TSFILE_DATAFRAME_MAX_OPEN_FILES` | 16 | Integer >= 1 |
| `query_workers` | `TSFILE_DATAFRAME_QUERY_WORKERS` | `min(4, os.cpu_count() or 1)` | Integer >= 1 |
| `query_parallel_min_rows` | `TSFILE_DATAFRAME_QUERY_PARALLEL_MIN_ROWS` | 8192 | Integer >= 1 |

An explicit parameter takes precedence over its environment variable. `None`
uses the environment variable, or the built-in default if it is unset. Options
are resolved once when constructing the frame; later environment changes do not
affect it. Subsets share their parent's runtime and limits. Invalid values raise
an error before dataset files or indexes are opened. Explicit resource options
require `use_index=True`; the default non-indexed mode ignores these environment
variables.

The prepared-series cache retains parsed native series metadata. It evicts the
least recently used idle entries and releases their native handles. Active
queries and dependent series pin shared time metadata, so the entry count can
temporarily exceed the limit until those queries finish. This is an entry-count
limit per runtime, not a process-wide memory limit. A value of `0` disables
retention after use. `descriptor_cache_size` bounds each of the named-descriptor
and series-route caches; `0` disables both. `max_open_files` bounds open readers,
and `query_workers=1` runs query groups serially. Multiple runtimes or worker
processes have separate limits.

## File-level properties

`TsFileWriter` and `TsFileTableWriter` accept binary properties while they are
Expand Down
12 changes: 6 additions & 6 deletions python/tests/test_dataset_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import pytest

import tsfile.dataset.index as index_module
import tsfile.dataset.runtime as runtime_module
from tsfile import (
ColumnCategory,
ColumnSchema,
Expand Down Expand Up @@ -421,9 +420,9 @@ def count_find_device(*args, **kwargs):
def test_runtime_descriptor_cache_evicts_least_recent_name(tmp_path, monkeypatch):
source = tmp_path / "devices.tsfile"
_write_runtime_devices_file(source)
monkeypatch.setattr(runtime_module, "_SERIES_DESCRIPTOR_CACHE_SIZE", 2)

with TsFileDataFrame(str(source), show_progress=False, use_index=True) as dataframe:
with TsFileDataFrame(
str(source), show_progress=False, use_index=True, descriptor_cache_size=2
) as dataframe:
names = [str(name) for name in dataframe.list_timeseries()]
find_device_calls = 0
original_find_device = dataframe._runtime.index.find_device_id
Expand Down Expand Up @@ -538,8 +537,9 @@ def test_prepared_query_reads_nullable_offset_window_in_arrow_batches(tmp_path):
runtime = dataframe._runtime
series = runtime.index.record(LOGICAL_SERIES, 0)
span = runtime.index.record(SERIES_FILE_SPAN, series[2])
with runtime.readers.acquire(0) as reader:
prepared = runtime.prepared.get(0, span[2], reader)
with runtime.readers.acquire(0) as reader, runtime.prepared.acquire(
0, span[2], reader
) as prepared:
with reader.query_prepared(prepared, offset=1, limit=7) as result:
batches = []
while True:
Expand Down
Loading
Loading