redis-rb / redis-client

Simple low level client for Redis 6+
MIT License
124 stars 60 forks source link

Implement RedisClient#measure_round_trip_delay #113

Closed casperisfine closed 1 year ago

casperisfine commented 1 year ago

Latency is returned as a Float in milliseconds.

For the Ruby driver, it's equivalent to measuring how long call("PING") takes, however with the Hiredis driver, the latency is measured without ever holding the GVL which allows to give a much more accurate measure that isn't impacted by GVL contention.

Ref: https://github.com/redis/hiredis-rb/issues/74

Test script:

def fibonacci( n )
  return  n  if ( 0..1 ).include? n
  ( fibonacci( n - 1 ) + fibonacci( n - 2 ) )
end

require "redis-client"
if ENV["DRIVER"] == "hiredis"
  require "hiredis-client"
end

client = RedisClient.new

threads = 10.times.map do
  Thread.new do
    loop do
      fibonacci(30)
    end
  end
end

5.times do
  puts "latency: #{client.measure_round_trip_delay}ms"
  sleep 1
end
$ DRIVER=ruby bundle exec ruby -I hiredis-client/lib/ /tmp/measure-latency.rb
latency: 1033.9850000143051ms
latency: 1039.7799999713898ms
latency: 1040.0930000543594ms
latency: 1050.2749999761581ms
latency: 1044.6280000209808ms
$ DRIVER=hiredis bundle exec ruby -I hiredis-client/lib/ /tmp/measure-latency.rb
latency: 0.307ms
latency: 0.351ms
latency: 0.236ms
latency: 0.221ms
latency: 0.321ms

Note: I definitely see the usefulness of this, but it requires to bypass quite a few layers, which concerns me a bit in term of maintenance. But I'll sleep on it.

cc @mperham @nateberkopec

casperisfine commented 1 year ago

Self note: the method name should probably reflect that it's the full server latency we're measuring (network + redis-server time to respond).

mperham commented 1 year ago

I called it RTT for round trip time, that's the industry standard acronym for ping time. "measure_rtt" or just "rtt" would be my suggestion for method name. I would prefer integer microseconds as the return value but traceroute does format RTT as float milliseconds so I can understand that choice.

https://en.wikipedia.org/wiki/Round-trip_delay

casperisfine commented 1 year ago

Ok, renamed it to measure_round_trip_delay. It's a bit of a mouthful but is clear.

I kept it as float milliseconds, as I think it's easier to work with in most cases, as that's generally the unit used for network operations.