{"id":16935312,"url":"https://github.com/dsander/rredis","last_synced_at":"2025-04-11T18:53:44.536Z","repository":{"id":3677338,"uuid":"4746872","full_name":"dsander/RReDis","owner":"dsander","description":"RReDis - a round robin database backed by redis","archived":false,"fork":false,"pushed_at":"2012-06-22T02:48:59.000Z","size":264,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-08T23:29:01.392Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dsander.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-06-22T02:41:26.000Z","updated_at":"2022-02-12T22:51:29.000Z","dependencies_parsed_at":"2022-08-19T01:00:29.014Z","dependency_job_id":null,"html_url":"https://github.com/dsander/RReDis","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsander%2FRReDis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsander%2FRReDis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsander%2FRReDis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsander%2FRReDis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsander","download_url":"https://codeload.github.com/dsander/RReDis/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248464590,"owners_count":21108238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T20:54:13.073Z","updated_at":"2025-04-11T18:53:44.514Z","avatar_url":"https://github.com/dsander.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"## RReDis\n\nhttps://github.com/dsander/RReDis\n\nRReDis is a round robin database backed by redis. It uses the brand new lua scripting feature of redis 2.6.\n\n\n## Getting started\n\nInstall the gem\n\n    gem install rredis\n\n\nStore some metrics\n    \n    require 'rredis'\n    rrd = RReDis.new\n\n    # We start two hours in the past\n    start = (Time.now-(3600*2)).to_i\n\n    # We pretend to update the data every 10 seconds for two hours\n    (2*3600/10).times do |step|\n      rrd.store \"example\", start+step*10, rand(100)\n    end\n\nFetch data from RReDis\n\n    require 'rredis'\n    rrd = RReDis.new\n\n    # Get the data from 5 minutes ago until now\n    puts rrd.get('example', Time.now-300, Time.now).inspect\n    # Get the data from one hour ago until 55 minutes ago\n    puts rrd.get('example', Time.now-3600, Time.now-3300, 'min').inspect\n    # Get the data from two hours ago until 90 minutes ago\n    puts rrd.get('example', Time.now-7200, Time.now-5400, 'max').inspect\nThe get function takes three or four arguments:\n\n*  The metric to query\n*  Starting time stamp for the timespan to return\n*  Ending time stamp for the timespan to return\n*  Optional aggregation method \n\n\nThe array returned contains two arrays, the first one with unix timestamps of the measurements, the second one the (aggregated) values.\n\n## Configuration\n\nPer default RReDis is configured to store one measurement every 10 seconds for one day (called native resolution from here on), and then aggregate the measurements for the following timespans:\n\n*  1 week at 1 minute resolution\n*  1 month at 15 minute resolution\n*  1 year at 1 hour resolution\n\nRReDis also stores the average, minima and maxima of aggregated measurements.\n\n# Configuration format\n\nRReDis default configuration:\n\n    {:steps=\u003e10, :rows=\u003e17280, \n     :aggregations=\u003e[\"average\", \"min\", \"max\"], \n     :rra =\u003e [ {:steps=\u003e60, :rows=\u003e10080, :xff=\u003e0.5},\n               {:steps=\u003e900, :rows=\u003e2976, :xff=\u003e0.5},\n               {:steps=\u003e3600, :rows=\u003e8760, :xff=\u003e0.5}]}\n\n`:steps` interval in seconds in which to store measurements\n\n`:rows`  amount of measurements to store, the timespan in seconds of the native resolution equals to `:steps`*`:rows`\n\n`:aggregations` array of aggregations to use for this measurement, currently available: `average`, `min`, `max`, `sum`\n\n`:rra`   array of archives to store historical data\n\n\nFor every `:rra`:\n\n`:steps` interval in seconds in which to aggregate the measurements of the next higher resolution\n\n`:rows`  amount of aggregations to store, the timespan in seconds of the archive equals to `:steps`*`:rows`\n\n`:xff`   the xfiles factor - determines if aggregated measurements are stored. 1.0 would require 10 of 10 measurements from the next higher resolution (either form a rra or the native resolution), 0.1 would require 1 of 10 measurements\n\n# Modify the configuration\nYou can either explicitly configure a metric via the `config` method:\n\n    rrd = RReDis.new  \n    rrd.config(\"metic\", {:steps =\u003e 10, :rows =\u003e 3})\n\n\nOr change the default configuration which will be applied to every measurement without an explicit configuration:\n\n    rrd = RReDis.new\n    rrd.default_config = {:steps =\u003e 10, :rows =\u003e 3}\n\n\n## Performance\n\nEven though redis supports a lot of data types, it was clearly not made to act as a round robin database, but still with lua scripting the performance is really nice. \n\nWith the default configuration RReDis is able to handle around 2.5k updates per second (ubuntu vm with two cores of an i5 750 in virtual box running on windows), which is still amazingly fast considering the complexity of the store.lua script.\n\nCheck out the default.rb script in the benchmark directory. Here are the results of my machine:\n\n    0.000395ms per op, 2529.6144076826317 op/s\n    415.557405432s for for 1051200 inserts\n    8639 stored measurements/aggregations\n    156 bytes used per stored measurement\n    6882960 measurements storable per gb of ram\n    794 metrics storable per gb of ram\n    5273285 redis commands performed\n    5 redis commands performed per stored measurement\n\nUsing pipelining, we are able to determine the limits of redis itself. On my box redis can handle about 10k updates per second. A \"advanced\" key-value store able to run a lua script 10 thousand times a second doing about 50 thousand internal operations per second is just plain amazing. \nHats off! @antirez\n\n\n## LICENSE:\n\n(The MIT License)\n\nCopyright (c) 2012 Dominik Sander\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsander%2Frredis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsander%2Frredis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsander%2Frredis/lists"}