Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building InfluxDB, an open source distributed events database

Building InfluxDB, an open source distributed events database

Slides for the InfluxDB talk I gave on March 25th, 2014 in Charlottesville.

Paul Dix

March 25, 2014
Tweet

More Decks by Paul Dix

Other Decks in Programming

Transcript

  1. About me… • Organizer NYC Machine Learning (4600+ members) •

    Author “Service Oriented Design with Ruby and Rails” • Creator of Feedjira, Typhoeus, and others • Columbia 2009* (CS) • YC (W13)
  2. How we arrived here • Had to build InfluxDB to

    even get to the product • Crowded space with no clear differentiation for us • Better opportunity as an open source platform
  3. What do other people do? • DB (Hbase, Cassandra, MySQL,

    Redis, etc) • Web services • Cron jobs or long running workers for summary tables
  4. Project Goals • Store metrics AND events • Horizontally scalable

    • Nothing else to run and manage • Shouldn’t have to write server code for downsampling/summaries
  5. InfluxDB • Written in Go • LevelDB for storage engine

    • No dependencies (other than glibc) • Distributed • HTTP API • SQL like query language
  6. Cool Integrations • StatsD Backend • CollectD Proxy • CLI

    (ruby or node) • Libraries for many languages • Graphite • OpenTSDB (soon)
  7. Data (with timestamp) [ { "name": "cpu", "columns": ["time", "value",

    "host"], "points": [ [1395168540, 56.7, "foo.influxdb.com"], [1395168540, 43.9, "bar.influxdb.com"] ] } ]
  8. Storage • Schema-less • Indexed on (series, column, time, sequence

    number) • Microsecond precision • Doesn’t store null column values • Millions of series
  9. Where against Regex select value from some_log_series where value =~

    /.*ERROR.*/ and time > "2014-03-01" and time < "2014-03-03"
  10. How data is distributed • Shards - contiguous blocks of

    time • Replication factor (read scalability) • Split - break blocks of time into multiple shards (write scalability)
  11. Split • Hashing db, series • Series data always lives

    in the same shard • Match regex and randomly distribute • Writes scalability at the cost of losing data locality
  12. Now a bit of code… • Shards - contiguous blocks

    of time • Servers have multiple shards • Query can come into any server and hit multiple shards (local or remote)
  13. responses := make([]chan *protocol.Response, 0) // shards are arranged by

    time. // set up response channels to collect results for _, shard := range shards { responseChan := make(chan *protocol.Response) // parallelize it! go shard.Query(querySpec, responseChan) responses = append(responses, responseChan) }
  14. // loop through in order pulling results. // Since shards

    are ordered they come back // in the right order. for _, responseChan := range responses { for { // ordered, processed results onto response. response := <-responseChan if *response.Type == endStreamResponse { break } } }
  15. ! ! // shard.go func (s *Shard) Query(q *QuerySpec, c

    chan *protocol.Response) { req := s.createRequest(q) s.server.Request(req, c) }
  16. ! func (s *Server) Request(r *protocol.Request, c chan *protocol.Response) {

    // sends request over the wire and returns } ! // single goroutine handles responses from server func (s *Server) handleResponses() { for { r := <-s.responses // returns the chan that was sent with // call to Request c := s.getResponseChannel(r) c <- r } }
  17. responses := make([]chan *protocol.Response, 0) // shards are arranged by

    time. // set up response channels to collect results for _, shard := range shards { responseChan := make(chan *protocol.Response) // parallelize it! go shard.Query(querySpec, responseChan) responses = append(responses, responseChan) }
  18. responses := make([]chan *protocol.Response, 0) // shards are arranged by

    time. // set up response channels to collect results for _, shard := range shards { responseChan := make(chan *protocol.Response, 10) // parallelize it! go shard.Query(querySpec, responseChan) responses = append(responses, responseChan) }
  19. Exciting features coming up… • Copy/move shards within the cluster

    • Custom functions in JS • Binary Protocol and Pubsub
  20. Our goal is to make it as easy to build

    an analytics product as it is to write a web application.