Service Log in YTsaurus Flow

Deprecated

Service Log is deprecated. For new code that periodically scans keys in a computation's internal or external state, use Key Visitor feature.

The connector code is available here.

Use the service log to regularly scan sorted tables. Unlike other connectors, it’s inherently infinite: after a table is fully read, it starts reading it again.

You can also scan multiple tables in parallel, joining them by key columns.

Important

Currently, the first column in the key must be a ui64 value, evenly distributed between 0 and (1 << 64) - 1. Typically, you can use a hash of the row ID for this value.

Important

You can run the source in finite mode by setting the finite parameter to true. In this mode, the table is read exactly once, or (if reading has already started) each partition reads its part of the table once.

This mode is mainly intended to simplify test writing.

Working with replicated tables

The service log supports replicated tables.

To access them directly, you need to specify all replica clusters in the table’s clusters attribute.

To access them via the meta-cluster RPC, it’s enough to specify the meta-cluster in the cluster attribute.

Important

Access via the meta-cluster RPC is only possible with FetchType = EFetchType::SelectRows.

Fullstates

You can specify multiple fetchers in the service log. This can be used for the “fullstate” scenario. A fullstate is a table external to the pipeline that contains data for the same keys for which there is a state in the pipeline. This table is periodically loaded into the pipeline. You can do this efficiently: when generating the service log, join the pipeline’s state table and the fullstate table by keys right away. This way, events are generated for keys that exist in at least one of the fetchers. This approach gives you two useful properties:

  • During a single joined pass of the service log, each state is touched once. Instead of twice — once for the main service log event and once for loading the fullstate row.
  • The pipeline can react to events where a key exists in the pipeline’s state but not in the external fullstate.

You can distinguish the case where “all non-key columns are null” from the case where “there is no key match” using the ispresent system column.

How to write tests

A common mistake is writing tests for the service log in finite mode (finite = true) while expecting it to see data generated by processing messages from other sources. With this approach, you can’t guarantee that the service log will see the expected rows during the scan: it might scan a certain key range before the rows appear there. Instead, use one of these approaches to write tests correctly:

  1. Manually load the rows you want the service log to see before starting the test. With this approach, make sure the test result doesn’t depend on whether the service log sees the other rows.
  2. Run two executions: in the first, load data from other sources; in the second, run only the service log source.
  3. Make the test non-finite (finite = false).

Important

When using FetchType = EFetchType::TableReader, you must set enable_dynamic_store_read = true on the table. Otherwise, the service log might not immediately see the most recent data version. This is usually not critical for production, but it breaks tests.

Source settings

The source class is NYT::NFlow::TServiceLogSource.

Static spec

NYT::NFlow::TUnitedParameters<NYT::NFlow::TServiceLogSource>

Source: yt/yt/flow/library/cpp/common/registry-inl.h

Parameter

Description

finite

Type: bool
Default value: false
Treat the source as finite: transition the stream to the completed state after reading all available messages. How the end of the data is determined depends on the connector.

table_joiner

Type: NYT::TIntrusivePtr<NYT::NFlow::TTableJoinerSpec>
Default value: {}
Joiner spec.

Additional parameters

update_info_period

Type: TDuration
Default value: 15s
Period for refreshing the source's auxiliary partition information. A connector may use this tick for status requests and read-session liveness checks.

byte_size_alpha

Type: double
Default value: 0.05
Exponential smoothing coefficient for the average byte total and message count per offset: larger values make the estimate react to new data faster.

In the static spec of the service log, you define a list of table fetchers to scan, joining them by key columns. Most often, there’s just one fetcher, and the source simply scans a single table.

NYT::NFlow::TTableJoinerSpec

Source: yt/yt/flow/library/cpp/connectors/servicelog/joiner.h

Parameter

Description

fetchers

Type: std::vector<NYT::TIntrusivePtr<NYT::NFlow::TFetcherInJoinerSpec>>
Default value: []
Fetcher specs.

NYT::NFlow::TFetcherInJoinerSpec

Source: yt/yt/flow/library/cpp/connectors/servicelog/joiner.h

Parameter

Description

table_path

Type: NYT::NYPath::TRichYPath
Default value: TString("")
Path to the table including the cluster (multiple clusters can be specified).

value_columns

Type: std::optional<THashSet<std::string>>
Non-key columns to read (by default, all columns are read).

attempts

Type: long
Default value: 1

retry_timeout

Type: TDuration
Default value: 5s

fetch_type

Type: NYT::NFlow::EFetchType
Default value: table_reader
Important parameter that affects the type of load on YT. See the EFetchType description.

prefix

Type: std::string
Default value: TString("")
Column name prefix to be added for non-key table columns.

In the fetcher settings, you specify which table to scan, which columns to take, and what prefix to use for these columns in the join result (if a join is performed).

Minimal spec example
"table_joiner" = {
    "fetchers" = [
        {
            "table_path" = <path to the table>;
        };
    ];
};

NYT::NFlow::EFetchType

Possible values

Description

select_rows

Supports dynamic (including replicated) tables. Does not support read-ahead; queries go directly to tablet nodes (recommended option).

table_reader

Supports dynamic and static tables. Supports read-ahead; queries go through the master node.

Dynamic spec

NYT::NFlow::TDynamicUnitedParameters<NYT::NFlow::TServiceLogSource>

Source: yt/yt/flow/library/cpp/common/registry-inl.h

Parameter

Description

desired_partition_count

Type: long
Default value: 5
Desired number of partitions. Estimate as 1 partition per 1 MB/s of stream.

desired_cycle_time

Type: TDuration
Default value: 12h
The source will try to maintain a message generation rate that traverses the entire table once every desired_cycle_time.

Additional parameters

unavailable_threshold

Type: TDuration
Default value: 5m
How long the source must be continuously unavailable for the partition to count as stably unavailable. Only time during which the job was running and seeing the failure counts: a gap between restarts is not charged, and any successful answer from the source resets the total.

throttler_period

Type: TDuration
Default value: 10s
Throttling period.

See also