lessons learned from building a multi-tenant saas content management system on mongo with c#
TRANSCRIPT
Lessons Learned from Building a Multi-Tenant Saas Content Management
System on Mongo with C#
Kevin WrightJonathan Roeder
Kevin Wright (The long-haired hippie one)◦ Over 100 years of experience! (Just look at this
PowerPoint Template!)◦ Worked on the Space Station!◦ 2 years of Mongo experience
Jonathan Roeder (The short-haired hipster one)◦ 10 years of High Scale eCommerce / CMS / Search◦ 1.5 years of Mongo experience
About Us
Founded in 1999 SaaS eCommerce and related services 40,000+ Online stores 330+ Employees $2.8B processed on our platform in 2012
http://www.volusion.com/careers/
Just who are you guys?
But Enough about Us
WHY write one?
The world needed ONE MORE!?!
Critical focus on Multi-Tenancy Focus on Small footprint / Efficient scaling
About CMS
What it is: .NET REST Service Standard use case of enabling CMS users to
define Meta schemas (Content & Property Types)
CRUD operations on Data that conforms to the Meta schemas (Content)
Structures for organizing Content (Content Lists and Folders)
About CMS
Initial approach programmatically provisioned a Mongo Database for each Tenant.
Reinventing the wheel with database management.
Suffering from two minute incremental boot up time per Database was untenable (get it!).
New approach: Embrace Sharding as the appropriate scale out approach
Multi-Tenancy Lessons Learned
Opt-in per Collection Don’t do it to earn your Sharding merit
badge Read the documentation three times. Implement four times. (a.k.a Prototype) The Along Came Polly joke will never get old
Sharding Lessons Learned
.NET static type system + MongoDB dynamic schema is like mixing Simon and Garfunkel …(it can be great if you don’t Garfunkel it up)
Driver allows for pure dynamic schema interaction but is maturing to allow type safe access via Lambdas and LINQ.◦ Aggregation framework tbd [CSHARP-601]
MongoDB Plus C# Equals?
KEVIN WILL DEMO Mongo SHELL MONGOVUE LINQPAD
DEMO TIME!
Be as static as you can be.◦ POCO types for each MongoDB Document schema
(Data Transfer Object, DTO pattern)◦ Leverage compile-time safety. The newest driver
makes it easy with Generics and Lambdas ◦ Duck-typing and magic strings are for gooses!
Explore very rich serialization hooks and levers◦ (SetIgnoreIfNullConvention, BsonExtraElements,
…)
C# MongoDB Data Modeling Lessons Learned
C# POCOs!
C# DTO POCOs!
C# DTO POCOs!
Now that you’ve created static types, leverage them!
C# DTO POCOs!
LINQ support is great. Just know that:◦ No projection [CSHARP-456]◦ Hard to mix in dynamic schema elements (use
Inject extension method)
Fall back to
MongoDB.Driver.Builders.Query<T> or QueryBuilder<T>◦ Mix in dynamic schema elements via non-generic
version
QUERYING with C#
Query Static and Dynamic in Combination
3 HIT COMBO
!!!
Laser focus your Updates
Updating with C#
Be careful with the blanket Save method!◦ Can’t stop it from Upserting◦ Often overkill to replace entire Document
Updating with C#
Data modeling without Joins Concurrency modeling without Transactions
MongoDB Concerns
Denormalize!
In a World Without Joins
If your data can’t be dirty, don’t denoramlize
Example: Store only the FolderId on Content Document instead of materialized Folder path◦ Pros: Updates are easy!◦ Cons: Queries are hard!◦ When wanting to find Content within child Folders,
must first query for all child Folders, then OR those IDs using the ‘In’ operator
But Sometimes, don’t Denormalize!
Simple Virtual Join
Simple Virtual Join
MongoDB.org approaches for actually retrieving the Folders : http://docs.mongodb.org/manual/tutorial/model-tree-structures/
Simple Virtual Join Continued
Optimistic Concurrency Benign Writes Benign Wrongs Compensate
Be prepared to carefully think this through. http://
blog.mongodb.org/post/475279604/on-distributed-consistency-part-1
http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/
In a World without Transactions
Vote!
While You’re Thinking of Questions