#15607·thingsboard

[错误] Cassandra 历史遥测查询在长时间运行后返回无数据;读取执行器卡在 Deque 处于满状态

作者: bcblr1993创建于 2026年5月9日更新于 2026年9月12日
标签BugBacklog

Component

  • ThingsBoard CE 4.1.0
  • Cassandra as historical time-series storage
  • Redis cluster as latest time-series storage Description After the platform runs for a period of time, the application is still alive and telemetry ingestion appears normal, but historical telemetry queries return no data from Cassandra. Restarting the ThingsBoard service restores the ability to query historical telemetry immediately. The deployment uses Redis for latest telemetry:
  • database.ts.type=cassandra
  • database.ts_latest.type=Redis-cluster So the issue is not about Redis latest telemetry. The failure happens when querying historical time-series data from Cassandra, for example dashboards or WebSocket/API historical telemetry queries. Observed behavior
  • ThingsBoard process continues running.
  • Latest telemetry/rule-chain related logic may still appear active.
  • Historical telemetry queries return no result / cannot load data.
  • Restarting ThingsBoard fixes the issue temporarily.
  • Before restart, the Cassandra read executor queue is full and stuck.
  • After restart, the read executor queue returns to normal. Evidence Before restart:
[Read] Permits queueSize = [200000] ... currBuffer = [1002]

After restart:

[Read] Permits queueSize = [0] ... currBuffer = [0]

Thread dump captured during the bad state shows both read dispatcher threads sleeping at:

org.thingsboard.server.dao.util.AbstractBufferedRateExecutor.dispatch(AbstractBufferedRateExecutor.java:227)

That corresponds to the branch where curLvl > concurrencyLimit, so the dispatcher does not consume new tasks from the queue. The application logs also contain repeated exceptions:

java.lang.IllegalStateException: Deque full
    at java.util.concurrent.LinkedBlockingDeque.add(...)
    at org.thingsboard.server.dao.util.AbstractBufferedRateExecutor.submit(...)
    at org.thingsboard.server.dao.nosql.CassandraAbstractDao.executeAsyncRead(...)
    at org.thingsboard.server.dao.timeseries.CassandraBaseTimeseriesDao.fetchPartitions(...)
    at org.thingsboard.server.dao.timeseries.CassandraBaseTimeseriesDao.getPartitionsFuture(...)
    at org.thingsboard.server.dao.timeseries.CassandraBaseTimeseriesDao.findAndAggregateAsync(...)
    at org.thingsboard.server.dao.timeseries.CassandraBaseTimeseriesDao.findAllAsync(...)

Why this looks like a bug The system can get into a state where:

  • currBuffer remains above CASSANDRA_QUERY_CONCURRENT_LIMIT
  • read dispatcher threads only sleep
  • queued Cassandra read tasks are no longer consumed
  • queue eventually reaches CASSANDRA_QUERY_BUFFER_SIZE
  • new historical telemetry reads fail with Deque full
  • only service restart clears the in-memory executor state This means the application does not self-recover from the Cassandra read executor stuck/full state. Configuration
yaml
database:
  ts:
    type: cassandra
  ts_latest:
    type: Redis-cluster
cassandra:
  query:

内容来源: thingsboard/thingsboard