Apache Cassandra and Go

Click here to load reader

  • date post

    15-Jan-2015
  • Category

    Technology

  • view

    3.518
  • download

    0

Embed Size (px)

description

Al Tobey (@AlTobey) is an Open Source Mechanic at DataStax. Prior to working at DataStax, Al was a Tech Lead of Compute and Data Services at Ooyala, which has been using Apache Cassandra since version 0.4 and these days uses Go in production. Al will be presenting a brief introduction to Go (#golang) and Cassandra, and how they are a great fit for each other. This talk will include code samples and a live demo.

Transcript of Apache Cassandra and Go

  • 1. Cassandra and Go @AlTobey Open Source Mechanic @ Datastax2013 DataStax Condential. Do not distribute without consent.!1

2. Open Source Mechanic Officially, Open Source Evangelist for Apache Cassandra Educate Ask (the right) questions Fix things Get the word out 3. Cassandra AP distributed database Dynamo x BigTable Robust data model Built-in multi-datacenter replication At-rest encryption Easy to use 4. Cassandra 2.0 Lightweight Transactions (a.k.a. CAS) Results paging for CQL (cursors) Eager retries Many optimizations all over Experimental triggers Note: Java 7 is required 5. Look familiar? CREATE TABLE demo (id UUID, name VARCHAR, dob TIMESTAMP); !INSERT INTO demo (id, name, created) VALUES (, Al Tobey, 2013-10-29); !SELECT name FROM demo; !DESCRIBE TABLE demo; !use system; !SELECT columnfamily_name FROM schema_columnfamilies WHERE keyspace_name = demo; ! 6. #golang Tiny language Strongly typed Simple concurrency primitives first-class functions Native, statically-linked code Garbage collection Excellent standard library Great community Open Source 7. Fizz Buzz package main !import ( "fmt" ) !func main() { for i := 0; i < 100; i++ { fmt.Printf("%d: ", i) !if i%3 == 0 { fmt.Printf("fizz") }!if i%5 == 0 { fmt.Printf("buzz") }!}}fmt.Printf("n") 8. Chocolate and Peanut Butter Cassandra is distributed and can handle highly concurrent load Go makes concurrency trivial A CQL native protocol driver already exists for Go (gocql) A Thrift driver is also available (gossie) 9. Schema CREATE KEYSPACE demo WITH REPLICATION = { 'class' : SimpleStrategy', 'replication_factor' : 1 }; !CREATE TABLE subscribers { id UUID, email VARCHAR, created TIMESTAMP, updated TIMESTAMP, deleted TIMESTAMP ); !INSERT INTO subscribers (id, email, created, updated, deleted) VALUES ( 4e7cd544-a72c-41a1-a004-74ea34e1e932, atobey@datastax.com, 2013-10-24T00:00:00+0000, 2013-10-26T00:00:00+0000, 9999-12-31T00:00:00+0000 ); !SELECT id, email, created, updated, deleted FROM subscribers; 10. Querying package main !import ( "fmt" "time" "tux21b.org/v1/gocql" "tux21b.org/v1/gocql/uuid" ) !type Record struct { Id uuid.UUID Email string Created time.Time Updated time.Time Deleted time.Time } 11. Querying func main() { cluster := gocql.NewCluster("127.0.0.1") cluster.Keyspace = "subscribers" cluster.Consistency = gocql.Quorum !! !! !}cass, err := cluster.CreateSession() if err != nil { panic(fmt.Sprintf("Error creating session: %v", err)) } defer cass.Close() sub := Record{} q := cass.Query( `SELECT id, email, created, updated, deleted FROM subscribers` ) q.Scan(&sub.Id, &sub.Email, &sub.Created, &sub.Updated, &sub.Deleted) fmt.Printf("Record: %vn", sub) 12. Go Web Services Go seems to be particularly popular for web services With good reasons The standard librarys HTTP server is quite good Deploy a single binary High concurrency Light resource usage 13. Hello WWW package main !import ( "fmt" "net/http" ) !func main() { http.HandleFunc(/index.txt", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, Ohai!n") } ) !}http.ListenAndServe(":8080", nil) 14. Skeezy: dont do this at home Written specifically for this talk No (known) heinous crimes https://github.com/tobert/skeezy 15. skeezy package main !import ( ) !func main () { // connect to Cassandra (same as before) ! !}// set up routes (with a twist) // start the web service (same as before) 16. skeezy - setting up routes http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir(./public/img/)) ) ) !http.HandleFunc(/c/, func(w http.ResponseWriter, r *http.Request) { q := cass.Query(`SELECT id FROM c WHERE postId=?`, id.Bytes()) q.Iter() !})c := Comment{} for iq.Scan(&c.Id, &c.ParentId, &c.Created) { fmt.Fprintf(w, %v, c) } 17. skeezy - globals? package main import () !var cass *gocql.Session !func main () { // var err error cass, err = cluster.CreateSession() // !}http.HandleFunc(/c/, func() { q := cass.Query() // }) 18. skeezy - closure func main () { // cass, err := cluster.CreateSession() // !)http.HandleFunc(/c/, func() { q := cass.Query( ) } 19. skeezy - responsible passing func main () { // cass, err := cluster.CreateSession() // !)http.HandleFunc(/c/, func() { cc := skeezy.ListPosts(cass, ) } 20. skeezy - returning data func main () { // cass, err := cluster.CreateSession() // !)http.HandleFunc(/c/, func() { cc := skeezy.ListPosts(cass, ) }!package skeezy !func ListPosts() []Comment { ret := make([]Comment, 1) for { ret = append(ret, c) } return ret } 21. skeezy - channels & goroutines func ListComments(cass *gocql.Session, id uuid.UUID) (chan *Comment) { cc := make(chan *Comment) !!}go func() { iq := cass.Query(` WHERE postId=?`, id.Bytes()).Iter() for { c := Comment{} if iq.Scan(&c.Id, &c.ParentId, &c.Created) { cc