[ 
https://issues.apache.org/jira/browse/CASSANDRA-14572?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17800171#comment-17800171
 ] 

Maxim Muzafarov commented on CASSANDRA-14572:
---------------------------------------------

Hi [~djoshi],

You're right, it is better to discuss the solution design first, and only then 
dig into the source code.

 

1. I've managed to remove the GC pressure in the last few commits, so it should 
now be fine to pull a metric value from the virtual table by metric name, but 
we still have to iterate over a collection to find a metric, which again is not 
so efficient as JMX MBeans as it has direct reference to a metric instance, and 
no CQL overhead.

The CollectionVirtualTableAdapter is a general approach to export any internal 
collections as virtual tables, it accepts the Iterable<C> interface as a data 
container. We can also implement narrower adapters e.g. one that accepts 
Map<String, C> as a data container, and if we solidify the vt model that the 
map key is always equal to the virtual table partition key (which is at least 
true for the metric collections), pulling will be slightly faster then. Such a 
trade-off depends on the usage pattern for virtual tables with metrics, pulling 
metrics every ~10-20 sec should be acceptable with the Iterable<C> interface 
(histograms are still expensive to pull often).

 

2. This is another compromise we have to make, each of these options has its 
pros and cons. I see three options here:
 - Commit the RawWalker implementations along with the model classes. Pros: 
classes are plain, keep the ant build simple, easy to debug. Cons: maintain 
cost if the RawWalker interface changes often, increase the amount of changes 
in the patch.
 - use an annotation processor to generate RawWalker implementation. Pros: no 
boilerplate implementation in the code, uses plain java, no extra dependency. 
Cons: additional code to maintain, increase the build complexity.
 - use a templating engine (e.g. the [javapoet, 
|https://github.com/square/javapoet]you meant something like that, right?) to 
generate implementations. Pros: no boilerplate code, a framework to create 
classes. Cons: increase the code complexity as we have to be aware of a new 
library, an extra dependency.

I assume that the RawWalker interface is relatively stable and rarely changes, 
so we don't need to change the implementation too often and/or generate it on 
the fly. In case we want to add a new column to a model, changes are also easy. 
So, if we want to remove the annotation processor, I would rather choose the 
first option. 
This is still a compromise, so please change your thoughts.

Here is how the generated code looks like:
{code:java}
public class MetricRowWalker implements RowWalker<MetricRow>
{
    /** {@inheritDoc} */
    @Override public void visitMeta(RowWalker.MetadataVisitor visitor)
    {
        visitor.accept(Column.Type.PARTITION_KEY, "name", 
java.lang.String.class);
        visitor.accept(Column.Type.REGULAR, "scope", java.lang.String.class);
        visitor.accept(Column.Type.REGULAR, "type", java.lang.String.class);
        visitor.accept(Column.Type.REGULAR, "value", java.lang.String.class);
    }

    /** {@inheritDoc} */
    @Override public void visitRow(MetricRow row, RowWalker.RowMetadataVisitor 
visitor)
    {
        visitor.accept(Column.Type.PARTITION_KEY, "name", 
java.lang.String.class, () -> row.name());
        visitor.accept(Column.Type.REGULAR, "scope", java.lang.String.class, () 
-> row.scope());
        visitor.accept(Column.Type.REGULAR, "type", java.lang.String.class, () 
-> row.type());
        visitor.accept(Column.Type.REGULAR, "value", java.lang.String.class, () 
-> row.value());
    }

    /** {@inheritDoc} */
    @Override
    public int count(Column.Type type)
    {
        switch (type)
        {
            case PARTITION_KEY: return 1;
            case REGULAR: return 3;
            case CLUSTERING: return 0;
            default: throw new IllegalStateException("Unknown column type: " + 
type);
        }
    }
}
{code}

> Expose all table metrics in virtual table
> -----------------------------------------
>
>                 Key: CASSANDRA-14572
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-14572
>             Project: Cassandra
>          Issue Type: New Feature
>          Components: Legacy/Observability, Observability/Metrics
>            Reporter: Chris Lohfink
>            Assignee: Maxim Muzafarov
>            Priority: Low
>              Labels: virtual-tables
>             Fix For: 5.x
>
>         Attachments: keyspayces_group responses times.png, keyspayces_group 
> summary.png, select keyspaces_group by string prefix.png, select 
> keyspaces_group compare with wo.png, select keyspaces_group without 
> value.png, systemv_views.metrics_dropped_message.png, thread_pools 
> benchmark.png
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> While we want a number of virtual tables to display data in a way thats great 
> and intuitive like in nodetool. There is also much for being able to expose 
> the metrics we have for tooling via CQL instead of JMX. This is more for the 
> tooling and adhoc advanced users who know exactly what they are looking for.
> *Schema:*
> Initial idea is to expose data via {{((keyspace, table), metric)}} with a 
> column for each metric value. Could also use a Map or UDT instead of the 
> column based that can be a bit more specific to each metric type. To that end 
> there can be a {{metric_type}} column and then a UDT for each metric type 
> filled in, or a single value with more of a Map<Text, Text> style. I am 
> purposing the column type though as with {{ALLOW FILTERING}} it does allow 
> more extensive query capabilities.
> *Implementations:*
> * Use reflection to grab all the metrics from TableMetrics (see: 
> CASSANDRA-7622 impl). This is easiest and least abrasive towards new metric 
> implementors... but its reflection and a kinda a bad idea.
> * Add a hook in TableMetrics to register with this virtual table when 
> registering
> * Pull from the CassandraMetrics registery (either reporter or iterate 
> through metrics query on read of virtual table)



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to