Сергей Туленцев 42bytes twitter.com/stulentsev

advertisement
Сергей Туленцев
42bytes
twitter.com/stulentsev
Что это за зверь?





база данных
NoSQL
документо-ориентированная
производительная
масштабирующаяся
Гибкая схема
В базу можно положить любой JSON
db.presentations.insert({ title : “Доклад”,
author : { name : “Сергей”,
last_name : “Туленцев”},
date : new Date()
});
Нет джойнов
Потому что они вредные и не нужны.
db.users.insert({ name : “Ivan Petrov”,
address : { country : “Russia”,
city : “Moscow”},
interests : [“women”, “hunting”]
});
Нет транзакций
Штука хорошая
Но страшно мешает масштабируемости
Есть атомарные апдейты
db.users.update({ _id : 1},
{ $set : { status : ‘banned’ }});
Есть индексы
db.foo.ensureIndex({ a : 1 });
db.foo.ensureIndex({ a : 1, b : -1});
db.foo.ensureIndex({c : 1}, {unique : true});
db.foo.ensureIndex({ d : 1}, {background : true});
db.foo.ensureIndex({e : 1}, {sparse : true});
Map/Reduce
Raw data
{
username : “Ivan”,
likes : 3,
text : “Preved world”
}
Map
var mapper = function () {
emit( this.username, { count : 1,
likes : this.likes})
}
Reduce
var reducer = function(key, values) {
var result = {count : 0, likes : 0};
values.forEach(function(value) {
result.count += value.count;
result.likes += value.likes;
});
return result;
}
Execute
db.runCommand({mapreduce : “comments”,
map : mapper,
reduce : reducer,
out : “mr_result”
});
PROFIT!
db.mr_result.find();
{_id : 1, value : {likes : 20, count : 3}}
{_id : 40, value : {likes : 0, count : 100}}
{_id : 55, value : {likes : 100500, count : 1}}
Server-side JavaScript
GridFS
Масштабирование
Кластер
config servers
client
mongod
mongod
mongos
replica set
mongod
mongod
mongod
mongod
mongod
mongod
mongod
Выбираем shard key
Определяет распределение данных
Очень трудно изменить
Самое важное решение в плане
производительности
Примеры
users {email : …, name : …}
twitter {user_id : …, event_id : …, text : …}
photos {photo_id : ???, photo_blob : …}
Чанки
Лимит – 64 Мб или 100,000 объектов
Разделяются по медианному ключу
Хранят диапазон значений
key from
key to
shard
min key
M
shard001
M
max key
shard002
Балансировка
В фоновом режиме
Данные не блокируются
Чтения – консистентны
Где использовать?
Например,
Статистика
Rich key/value store
Прототипирование
Динамические данные (опросы, CMS)
Tips & Tricks
Initial data import
Импорт может тормозить
db.runCommand( { split : ‘test.foo’,
middle : { _id : 1000} );
db.runCommand( {moveChunk : ‘test.foo’,
find : { _id : 500 },
to : “shard001” });
Cached counters
db.users.find()
{ _id : “123”, name : “Ivan”, friends : [1, 2, 3, …]}
db.users.update({ _id : “123”,
{$push : { friends : 55},
$inc : { friend_count : 1} });
Covered indexes
db.users.ensureIndex( {email : 1, name : 1});
Random access vs right-balanced
Надо держать весь индекс в RAM
Random access vs right-balanced
Нужно держать только небольшую часть
Hot writes
memory mapped files
Документы должны быть в памяти
Спасибо за внимание
Сергей Туленцев
42bytes
sergei.tulentsev@gmail.com
twitter.com/stulentsev
Download