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

Ben Chan edited comment on CASSANDRA-5483 at 6/11/14 5:37 PM:
--------------------------------------------------------------

I'm sorry I can't think this through very deeply at the moment, so please allow 
a little slack if I say something incorrect. I'm writing this during a small 
window of time (where I can't do anything else) in a crisis I'm dealing with.

bq. Why is command part of events instead of sessions?

It was a somewhat arbitrary design decision. I can move it over to sessions. 
The only real reason was historical (see the Mar 3 comment); it was a 
proof-of-concept that never got followed up upon until just now.

bq. Also: should use an enum internally. Logging as string representation is 
fine.

Just to be clear, you mean Java code should work with an enum, and the actual 
cql table column is fine as a string?

The code actually does use an enum (of sorts; not an Enum proper), the 
traceType. The traceType is passed to Tracing#getCommandName to look up the 
String for command name.

bq. It makes people grumpy when we break JMX signatures. Can we add a new 
overload instead, preserving the old? This should cut down on some of the code 
churn in StorageService as well.

I will admit that I didn't really consider the entire ecosystem of tools that 
use JMX to control Cassandra (though note that I did mention the JMX api change 
in a Mar 8 comment "... the server isn't going to work with old versions of 
nodetool. And a newer nodetool still won't work with older server versions.").

bq. It's a minor thing to get hung up on, but I'm not wild about all the work 
needed to propagate TTLs around. Is it really super important to persist repair 
traces much longer than queries? If so, what if we used a separate table and 
just allowed users to modify the default ttl? (The original trace code predates 
default TTLs, I think, or we would have made use of it there.)

I guess the question is how many different types of things (bootstrap, repair, 
query, decommission, ... anything else?) might eventually end up being traced. 
If n is small, then having n tables may be fine.

The logic was this (see Mar 1-3 discussion): Repair can take a long time, so 24 
hours may be too short of a ttl.

I recall reading about problematic repairs taking several days, which wouldn't 
mix well with a 24 hour ttl.

bq. Also have a nagging feeling that the notify/wait logic in StorageService + 
TraceState is more complex than necessary.

If there is guaranteed to only ever be one consumer of notifications at a time, 
then the updated v15 logic seems fine. But if there are ever two threads 
polling the same TraceState, then there could be dropped notifications. The 
problem (I believe) is that all consumers may not be in a wait state at the 
moment when notifyAll is signalled. This means a notification could be missed, 
right? I'm not experienced in Java concurrency, and this isn't the best time 
for me to slowly think things through, so it's quite possible I'm wrong here.

But it does seem reasonable there will only ever be one polling thread for any 
given tracing session, so the v15 code should work fine in that respect, as far 
as my cursory inspection goes.

Note, however, that the polling in this case is a heuristic only. Meaning that 
it's *likely* that an external trace happened somewhere around this time plus 
or minus (as far as I know, there is no way in Cassandra to be notified of cf 
updates). Which means that the actual trace may only arrive *after* the 
notification, meaning that for two notifications ~maxWait seconds apart, your 
logging of events might be maxWait seconds late:

{noformat}
time  action                result
----  ------                ------
   0  receive notification  no events found
  10  event A
1000  receive notification  sendNotification(event A)
{noformat}

This is why I had an exponential backoff. Because I wanted to poll with high 
frequency for a likely event, polling less and less often as the notification 
recedes into the past. There are, of course, endless tweaks possible to this 
basic algorithm. It depends upon what you can assume about the likely time 
distribution of the events hinted at by the notification.

{noformat}
time  action                result
----  ------                ------
   0  receive notification  no events found
   2  poll                  no events found
   4  poll                  no events found
   8  poll                  no events found
  10  event A
  16  poll                  sendNotification(event A)
  32  poll                  no events found
1000  receive notification  no events found
{noformat}

bq. I should note I've made no attempt to corroborate this behaviour is 
sensible; I've only simplified it.

Any feedback would be welcome. As I've said before, heuristics are messy. I 
talked about the reasoning behind my design decisions, and a possibility for an 
alternate implementation (with attendant tradeoffs) in a Mar 17 comment. I 
honestly thought I'd get more comments on it at the time, but it's possible the 
patch had already gotten into TL; DR territory even then.

---

Okay my short break from reality is over. Time to panic.

---

Edit: some more dead time (hurry up and wait). Thought some more about trace 
notifications.



was (Author: usrbincc):
I'm sorry I can't think this through very deeply at the moment, so please allow 
a little slack if I say something incorrect. I'm writing this during a small 
window of time (where I can't do anything else) in a crisis I'm dealing with.

bq. Why is command part of events instead of sessions?

It was a somewhat arbitrary design decision. I can move it over to sessions. 
The only real reason was historical (see the Mar 3 comment); it was a 
proof-of-concept that never got followed up upon until just now.

bq. Also: should use an enum internally. Logging as string representation is 
fine.

Just to be clear, you mean Java code should work with an enum, and the actual 
cql table column is fine as a string?

The code actually does use an enum (of sorts; not an Enum proper), the 
traceType. The traceType is passed to Tracing#getCommandName to look up the 
String for command name.

bq. It makes people grumpy when we break JMX signatures. Can we add a new 
overload instead, preserving the old? This should cut down on some of the code 
churn in StorageService as well.

I will admit that I didn't really consider the entire ecosystem of tools that 
use JMX to control Cassandra (though note that I did mention the JMX api change 
in a Mar 8 comment "... the server isn't going to work with old versions of 
nodetool. And a newer nodetool still won't work with older server versions.").

bq. It's a minor thing to get hung up on, but I'm not wild about all the work 
needed to propagate TTLs around. Is it really super important to persist repair 
traces much longer than queries? If so, what if we used a separate table and 
just allowed users to modify the default ttl? (The original trace code predates 
default TTLs, I think, or we would have made use of it there.)

I guess the question is how many different types of things (bootstrap, repair, 
query, decommission, ... anything else?) might eventually end up being traced. 
If n is small, then having n tables may be fine.

The logic was this (see Mar 1-3 discussion): Repair can take a long time, so 24 
hours may be too short of a ttl.

I recall reading about problematic repairs taking several days, which wouldn't 
mix well with a 24 hour ttl.

bq. Also have a nagging feeling that the notify/wait logic in StorageService + 
TraceState is more complex than necessary.

If there is guaranteed to only be one consumer of notifications at a time, then 
the updated v15 logic seems fine. But if there are ever two traces going on 
(either of different or the same type; are you allowed to have two simultaneous 
repairs of different keyspaces?) which require update notifications, then there 
could be dropped notifications. The problem (I believe) is that all consumers 
may not be in a wait state at the moment when notifyAll is signalled. This 
means a notification could be missed, right? I'm not experienced in Java 
concurrency, and this isn't the best time for me to slowly think things 
through, so it's quite possible I'm wrong here.

However, if you can be completely sure there will never be concurrent repair 
traces happening on the same node, or any other trace types (whatever types are 
added in the future) that require update notifications in order to implement 
on-the-fly reporting, then that issue is moot, and v15 should work fine, as far 
as my cursory inspection goes.

bq. I should note I've made no attempt to corroborate this behaviour is 
sensible; I've only simplified it.

Any feedback would be welcome. As I've said before, heuristics are messy. I 
talked about the reasoning behind my design decisions, and a possibility for an 
alternate implementation (with attendant tradeoffs) in a Mar 17 comment. I 
honestly thought I'd get more comments on it at the time, but it's possible the 
patch had already gotten into TL; DR territory even then.

---

Okay my short break from reality is over. Time to panic.


> Repair tracing
> --------------
>
>                 Key: CASSANDRA-5483
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-5483
>             Project: Cassandra
>          Issue Type: Improvement
>          Components: Tools
>            Reporter: Yuki Morishita
>            Assignee: Ben Chan
>            Priority: Minor
>              Labels: repair
>         Attachments: 5483-full-trunk.txt, 
> 5483-v06-04-Allow-tracing-ttl-to-be-configured.patch, 
> 5483-v06-05-Add-a-command-column-to-system_traces.events.patch, 
> 5483-v06-06-Fix-interruption-in-tracestate-propagation.patch, 
> 5483-v07-07-Better-constructor-parameters-for-DebuggableThreadPoolExecutor.patch,
>  5483-v07-08-Fix-brace-style.patch, 
> 5483-v07-09-Add-trace-option-to-a-more-complete-set-of-repair-functions.patch,
>  5483-v07-10-Correct-name-of-boolean-repairedAt-to-fullRepair.patch, 
> 5483-v08-11-Shorten-trace-messages.-Use-Tracing-begin.patch, 
> 5483-v08-12-Trace-streaming-in-Differencer-StreamingRepairTask.patch, 
> 5483-v08-13-sendNotification-of-local-traces-back-to-nodetool.patch, 
> 5483-v08-14-Poll-system_traces.events.patch, 
> 5483-v08-15-Limit-trace-notifications.-Add-exponential-backoff.patch, 
> 5483-v09-16-Fix-hang-caused-by-incorrect-exit-code.patch, 
> 5483-v10-17-minor-bugfixes-and-changes.patch, 
> 5483-v10-rebased-and-squashed-471f5cc.patch, 5483-v11-01-squashed.patch, 
> 5483-v11-squashed-nits.patch, 5483-v12-02-cassandra-yaml-ttl-doc.patch, 
> 5483-v13-608fb03-May-14-trace-formatting-changes.patch, 
> 5483-v14-01-squashed.patch, 5483-v15.patch, ccm-repair-test, 
> cqlsh-left-justify-text-columns.patch, prerepair-vs-postbuggedrepair.diff, 
> test-5483-system_traces-events.txt, 
> trunk@4620823-5483-v02-0001-Trace-filtering-and-tracestate-propagation.patch, 
> trunk@4620823-5483-v02-0002-Put-a-few-traces-parallel-to-the-repair-logging.patch,
>  tr...@8ebeee1-5483-v01-001-trace-filtering-and-tracestate-propagation.txt, 
> tr...@8ebeee1-5483-v01-002-simple-repair-tracing.txt, 
> v02p02-5483-v03-0003-Make-repair-tracing-controllable-via-nodetool.patch, 
> v02p02-5483-v04-0003-This-time-use-an-EnumSet-to-pass-boolean-repair-options.patch,
>  v02p02-5483-v05-0003-Use-long-instead-of-EnumSet-to-work-with-JMX.patch
>
>
> I think it would be nice to log repair stats and results like query tracing 
> stores traces to system keyspace. With it, you don't have to lookup each log 
> file to see what was the status and how it performed the repair you invoked. 
> Instead, you can query the repair log with session ID to see the state and 
> stats of all nodes involved in that repair session.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to