61
OrigoDB Build faster systems faster

OrigoDB - take the red pill

Embed Size (px)

DESCRIPTION

Slides from a 3 hour OrigoDB presentation targeted at developers and architects.

Citation preview

Page 1: OrigoDB - take the red pill

OrigoDBBuild faster systems faster

Page 2: OrigoDB - take the red pill

Robert Friberg

• Design, build and maintain systems for clients at Devrex• Trainer – Microsoft NET, SQL Server, java, perl, python, linux• Machine learning, AI• Squash fanatic• @robertfriberg, [email protected]

Page 3: OrigoDB - take the red pill

Why?

ServiceLayer

DomainLayer

Data AccessLayer

RelationalModel

Views/SP’sXBuild faster systems faster

Page 4: OrigoDB - take the red pill

What is OrigoDB?

• In-memory database toolkit• Code and data in same process• Write-ahead command logging and snapshots• Open Source single DLL for NET/Mono• Commercial server with mirror replication

Page 5: OrigoDB - take the red pill

.NET Process Storage

Engine

2. Execute command

Handles queries and commands, guards model

1. AppendToLogPlaceOrderCommand

Snapshot

Client codepasses commandsand queries

PlaceOrderCommand

NewCustomerCommand

IncreaseInventoryLevelCommand

PlaceOrderCommand

PlaceOrderCommand

Snapshot

time

In-memoryModel

How does it work?

Page 6: OrigoDB - take the red pill

Demand drives change

• Performance• Data volume• Scalability• Availability• Modeling

• NoSQL

• Big data

• Graph

• Real time analytics

• In-memory computing

• Column stores

One size (RDBMS) no longer fits allPolyglot Persistence

Page 7: OrigoDB - take the red pill

B-trees and Transactions

LOG

DATA 64KB blocks w 8x8KB pagesLogical BTREE of 8kb data pagesIn the buffer pool (cache)

BufferManager

Transactions append inserted, deleted, original and modified pages to the LOG

• Fill factor• Page splits• Clustered index• Checkpoint

Page 8: OrigoDB - take the red pill

When?

• Whenever data fits in RAM• Alternative to general RDBMS OLAP/OLTP• Complex models and transactions• In-memory analytics• Traceability requirements (complete history of events)

Page 9: OrigoDB - take the red pill

Core framework types

Page 10: OrigoDB - take the red pill

Start your engines!

var engine = Engine.LoadOrCreate<SalesModel>();

// lambda queryvar customer = engine.Execute(db => db.Customers.GetById(42));

//Command objectvar cmd = new PlaceOrderCommand(customer.Id, newOrder);engine.Execute(cmd);engine.Close();

Page 11: OrigoDB - take the red pill

• 2 Core, 8GB RAM Cloud VM• IIS Web, SPA, ajax, ASP.NET MVC3• OrigoDB Server same host, currently 4GB process memory• 3k blogs, 500k posts, 500k keywords, 33 million links• Journal 1 GB, no snapshots, growth ~ 8MB/day

http://geekstream.devrexlabs.com

Page 12: OrigoDB - take the red pill

• Environmental news referral since 1997• 100 articles/day, fulltext search, summaries, categories, sources,

metadata• 5000 subscribers, clients, users, billing• Email history, weekly newsletters• < 4 GB Total RAM

Page 13: OrigoDB - take the red pill

Modeling

Page 14: OrigoDB - take the red pill

Creating a data model

• Domain specific vs. Generic vs. Hybrid• Rich vs. Anemic• Explicit vs. Implicit commands• References vs. Foreign keys

Page 15: OrigoDB - take the red pill

Computational model types

• Interpreter hosting – Javascript, Roslyn• Lucene index• Machine learning models (Accord.NET)

Page 16: OrigoDB - take the red pill

Object oriented domain modeling

• DDD?• Entities and collections• Choose collections wisely – space/time tradeoffs• Transaction script pattern or thin commands• Avoid CRUD

Page 17: OrigoDB - take the red pill

Silly Relational

[Serializable] public class RelationalModel : Model { private DataSet _dataset;

public RelationalModel() { _dataset = new DataSet(); } //... ExecuteQuery and ExecuteCommand omitted }

Page 18: OrigoDB - take the red pill

Generic Relational

[Serializable] public class RelationalModel : Model { Dictionary<string,SortedDictionary<object>> _tables; }

Page 19: OrigoDB - take the red pill

Domain specific relational

[Serializable] public class Model : Model { SortedDictionary<int,Customer> _customers; SortedDictionary<int,Order> _orders; SortedDictionary<int,Product> _products; SortedDictionary<string,Customer> _customersByName; }

[Serializable] public class Order { public int CustomerId; //foreign key vs. reference }

Page 20: OrigoDB - take the red pill

JS interpreter hosting (V8)

[Serializable] public class JurassicModel : Model { private ScriptEngine _scriptEngine;

public JurassicModel() { _scriptEngine = new ScriptEngine(); _scriptEngine.Execute("var model = {}"); } //... ExecuteQuery and ExecuteCommand omitted }

Page 21: OrigoDB - take the red pill

Commands

• Serial execution• Exclusive access to the model• Transition the model from one valid state to the next

s0 s1 s2t1 t2

Page 22: OrigoDB - take the red pill

Command guidelines

• No side effects or external actions• No external dependencies• Unhandled exceptions trigger rollback (full restore)• Call Command.Abort() to signal exception

Page 23: OrigoDB - take the red pill

The model is an object graph

TaskListTask

Task

Task

TaskList

Task

Task

Task

Task

Category

Category

Category

Category

TaskModel

Page 24: OrigoDB - take the red pill

Query alternatives

• Ad-hoc lambda: Engine.Execute(Func<M,R> query)• Derive from Query<M,R>• Compiled LINQ: Engine.Execute<R>(string, args)

Page 25: OrigoDB - take the red pill

Query guidelines

• Know thy object graphs• Don’t modify the model

Page 26: OrigoDB - take the red pill

Demo: HockeySkolan

• ASP.NET MVC 3 with backing OrigoDB• Domain specific model + CmsModel• Anemic model => fat commands, model is data

Page 27: OrigoDB - take the red pill

OrigoDB WorkshopModule 3 - Testing

Page 28: OrigoDB - take the red pill

Automated Test alternatives

• Transparent testing of domain behavior: entities, model• Test commands, queries, entities on model without engine• Test with in-memory storage• Full stack testing – slow, requires cleanup

Page 29: OrigoDB - take the red pill

In-memory storage

• Non persistent command journal and snapshots• Mimics FileStore using MemoryStreams• Tests serialization/identity issues

var config = EngineConfiguration.Create().ForIsolatedTest();

OR: config.SetCommandStoreFactory(cfg => new InMemoryCommandStore(cfg));

config.SetSnapshotStoreFactory(cfg => new InMemorySnapshotStore(cfg));

Page 30: OrigoDB - take the red pill

Demo: RedisModel

• Testing model behavior with NUnit

Page 31: OrigoDB - take the red pill

OrigoDB WorkshopModule 4 – Hosting

Page 32: OrigoDB - take the red pill

Direct in-process engine creation

• Static Engine methods• Create()• LoadOrCreate()• Load()

• Returns: Engine, Engine<M>

Engine<MyModel> engine = Engine.LoadOrCreate<MyModel>();

Page 33: OrigoDB - take the red pill

Engine.For<M>()

• Returns IEngine<M>() or derivative• Reuse based on EngineConfiguration.Location property• Remote or in-process• ILocalEngineClient<M>• IRemoteEngineClient<M>

• Running engines are tracked by Config.Engines

Page 34: OrigoDB - take the red pill

Db.For<M>()

• Returns a proxy for M• Remote or Local analogous to Engine.For<M>

Page 35: OrigoDB - take the red pill

x64 vs. x32

• Core Library compiled with AnyCPU• x32 = 32-bit pointers, max 4GB• x64 = 64-bit pointers• Server ships with x64 and x32 binaries

Page 36: OrigoDB - take the red pill

IIS Hosting

• Disable application pool recycling• Ensure single process, no farming or LB• Litter controllers with Db.For<M>() / Engine.For<M>()• Or put a static ref somewhere, eg Global.asax

Page 37: OrigoDB - take the red pill

Proxy

• Proxy has same interface as the Model• Method calls are intercepted• void methods interpreted as commands (and logged)• other methods interpreted as queries• Can be overriden with attributes• Local or remote, cluster

Page 38: OrigoDB - take the red pill

Demo: Let’s build a key/value store

• New project• Reference origodb.core• Define KeyValueStoreModel• void Put(key, value)• object Get(key,value)• bool Exists(key, value)• bool Remove(key,value)

• Add some unit tests

Page 39: OrigoDB - take the red pill

OrigoDB WorkshopModule 5 – Configuration

Page 40: OrigoDB - take the red pill

EngineConfiguration class – key properties• AsyncJournaling• EnsureSafeResults• Kernel• Location• PacketOptions• PersistenceMode• SnapshotBehavior

Page 41: OrigoDB - take the red pill

EngineConfiguration.Location property• File location for FileStorage• Connection string when SqlStorage• Defaults (when null)• Will look in app.config for connection string• Type name of model• Current working directory• App_Data in web context

• Magic• mode=remote;host=10.0.0.20;port=3001

Page 42: OrigoDB - take the red pill

Persistence modes

• Journaling (default)• SnapshotPerTransaction• ManualSnapshots

var config = EngineConfiguration.Create();

config.PersistenceMode = PersistenceMode.SnapshotPerTransaction;

var db = Engine.For<MyModel>(config);

Page 43: OrigoDB - take the red pill

Kernels

• OptimisticKernel (default)• RoyalFoodTaster

var config = EngineConfiguration.Create();

config.Kernel = Kernels.RoyalFoodTaster;

var db = Db.For<MyModel>(config);

Page 44: OrigoDB - take the red pill

Logging

• Logging disabled by default

//enable loggingConsoleLogger.MinimumLevel = LogLevel.Trace;

//Plugin custom loggerLogProvider.SetFactory(new Log4NetLoggerFactory());

Page 45: OrigoDB - take the red pill

Extensibility

• EngineConfiguration methods• SetAuthorizerFactory()• SetSynchronizerFactory()• SetCommandStoreFactory()• SetFormatterFactory()

Page 46: OrigoDB - take the red pill

ProtobufFormatter

• Protocol Buffers by Google• IFormatter wrapper around protobuf-net by @marcgravell• Contract based as opposed to embedded metadata• Compact, fast, loose coupling, cross platform• Configure with attributes or code • Use it!

Page 47: OrigoDB - take the red pill

Protobuf: Attribute based configuration [ProtoContract]    public class Company    {       [ProtoMember(1)]

       public string Name { get; set; }

       [ProtoMember(2)]

       public List<Employee> Employees { get; set; }    }

Page 48: OrigoDB - take the red pill

Protobuf: Code-based configuration

var typeModel = TypeModel.Create();

typeModel.Add(typeof (Company), false)

      .Add(1, ”Name")

      .Add(2, ”Employees");

Page 49: OrigoDB - take the red pill

Inject formatter factory

//use helper methods

ProtoBufFormatter.ConfigureSnapshots<MyModel>(config, typeModel);

ProtoBufFormatter.Configure(config, FormatterUsage.Results, typeModel);

//or do it yourself

config.SetFormatterFactory((cfg,fu)

=> new ProtoBufFormatter<MyModel>(typeModel),

FormatterUsage.Snapshot);

Page 50: OrigoDB - take the red pill

OrigoDB WorkshopModule 6 – Immutability

Page 51: OrigoDB - take the red pill

Immutability and blockingwriter

reader

Page 52: OrigoDB - take the red pill

States share immutable objects

s0

s3s1s2

(Animated slide)

Page 53: OrigoDB - take the red pill

Exampleimmutablemodel

Page 54: OrigoDB - take the red pill

Exampleimmutableentity

Page 55: OrigoDB - take the red pill

Immutable command example

Page 56: OrigoDB - take the red pill

Configuration

Page 57: OrigoDB - take the red pill

OrigoDB WorkshopModule 6 – Server

Page 58: OrigoDB - take the red pill

OrigoDB Server

• Console Application or Windows Service• Process hosting single Engine / Model• Ad-hoc Linq / Razor queries• Javascript API• Primitive web based UI• Commercial License• Multiserver replication

Page 59: OrigoDB - take the red pill

Transparent client migration

• Configuration strings:• mode=embedded• mode=remote;host=10.10.10.10;port=3001

Page 60: OrigoDB - take the red pill

Lab M6

• Follow the OrigoDB Server online tutorialhttp://origodb.com/

Page 61: OrigoDB - take the red pill

Thank you for listening!

• http://origodb.com• http://dev.origodb.com• http://github.com/devrexlabs• http://geekstream.devrexlabs.com• @robertfriberg, @devrexlabs