Nosql

CAP

Consistency

Every read receives the most recent write or an error

Availability

Every request receives a (non-error) response – without the guarantee that it contains the most recent write

Partition tolerance

The system continues to operate despite an arbitrary number of messages being dropped (or delayed) by the network between nodes

Img

cap.png

BASE

A BASE system gives up on consistency.

BA

B\asically A\vailable indicates that the system does guarantee availability, in terms of the CAP theorem.

S

S\oft state indicates that the state of the system may change over time, even without input. This is because of the eventual consistency model.

E

E\ventual consistency indicates that the system will become consistent over time, given that the system doesn't receive input during that time.

So,

  • Database systems designed with traditional ACID guarantees in mind such as RDBMS choose consistency over availability
  • whereas systems designed around the BASE philosophy, common in the NoSQL movement for example, choose availability over consistency.

Characteristics

Horizontal scaling

scale.png

Schema less

  • Riak has schema
  • Elasticsearch has optional schema

Schema less cont.

But in most cases schema is flexible and optional

Implementation

Mongodb

  • Document-Based
  • BSON
  • Ugly query language

Example mongo query

db.inventory.insertMany([
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);

Redis

  • Key-Value store
  • Ability to create dump to filesistem

Riak KV

  • Key-Value
  • JSON
  • gRPC communication(protobuf)

Riak TS

  • Db for storing time series data
  • Use SQL too modeling and CRUD data

Riak TS example

CREATE TABLE GeoCheckin
(
  region       VARCHAR   NOT NULL,
  state        VARCHAR   NOT NULL,
  time         TIMESTAMP NOT NULL,
  weather      VARCHAR   NOT NULL,
  temperature  DOUBLE,
  PRIMARY KEY (
    (region, state, QUANTUM(time, 15, 'm')),
    region, state, time
  )
);

Riak TS time

https://docs.riak.com/riak/ts/1.5.2/using/timerepresentations/index.html

Elasticsearch

  • Document Based
  • Build on top of Lucene
  • Each shard is Lucene index
  • REST for interact with db
  • SQL for interact with db

NoSQL example

RiakKV

Get started

version: "2"
services:
  coordinator:
    image: basho/riak-kv
    ports:
      - "8087:8087"
      - "8098:8098"
    environment:
      - CLUSTER_NAME=riakkv
    labels:
      - "com.basho.riak.cluster.name=riakkv"
    volumes:
      - schemas:/etc/riak/schemas
  member:
    image: basho/riak-kv
    ports:
      - "8087"
      - "8098"
    labels:
      - "com.basho.riak.cluster.name=riakkv"
    links:
      - coordinator
    depends_on:
      - coordinator
    environment:
      - CLUSTER_NAME=riakkv
      - COORDINATOR_NODE=coordinator

volumes:
  schemas:
    external: false

Start

docker-compose up -d

Scale

docker-compose scale coordinator=1 memeber=4

Connect to db

require 'riak'

client = Riak::Client.new(pb_port: 8087)

Fetch data

fetched1 = my_bucket.get('one')
fetched2 = my_bucket.get('two')
fetched3 = my_bucket.get('three')

ap fetched1.data 
ap fetched2.data 
ap fetched3.data.to_json

Fetch data cont.

1
"two"
"{\"myValue\":3}"

Add complex data

book = {
  :isbn => '1111979723',
  :title => 'Moby Dick',
  :author => 'Herman Melville',
  :body => 'Call me Ishmael. Some years ago...',
  :copies_owned => 3
}

books_bucket = client.bucket('books')
new_book = books_bucket.new(book[:isbn])
new_book.data = book
new_book.store

Update data

fetch_book = books_bucket.get(book[:isbn])
fetch_book.data[:copies_owned] = 1000
fetch_book.store

Delete data

new_book.delete

Try to query data

order_summary = {
    customer_id: 1,
    summaries: [
	{
	    order_id: 1,
	    total: 415.98,
	    order_date: Time.parse('2013-10-1 14:42:26')
	},
	{
	    order_id: 2,
	    total: 359.99,
	    order_date: Time.parse('2013-10-15 16:43:16')
	},
	{
	    order_id: 3,
	    total: 74.98,
	    order_date: Time.parse('2013-11-3 17:45:28')
	}
    ]
}

Try to query data cont.

order_bucket = client.bucket('Orders')
orders.each do |order|
  order_riak = order_bucket.new(order[:order_id].to_s)
  order_riak.data = order
  order_riak.store
end

order_summary_bucket = client.bucket('OrderSummaries')
os = order_summary_bucket.new(order_summary[:customer_id].to_s)
os.data = order_summary
os.store

Pain

pain.png

Thanks!