CLICKHOUSE-2724: website refactoring (#668)
* Split website and doc * Add Host directive to robots.txt * Make new favicon.ico from svg * Reformat code * Add some obscurity to email to limit it's inclusion to email spam databases * Mention SQL in descriptions * Put logo near main title * Add navbar * Update feedback text on tutorial page * Reformat code on tutorial page * Better inline svg * Move javascript to bottom in reference * Mark external links on main & tutorial * Copy footer from main to tutorial * Move Telegram higher * Get rid of hidden content * Update jQuery + add it on index * Rewrite plain JS with jQuery on index * Swap Contacts and Download * Some title tuning * Move Source link to corner * Slow scroll * New first screen * First screen tuning * Add github pages script * Checkout in proper place * more nofollow * Basic mobile support * Add some temporary icon (SIL licensed) * Fix horizontal scroll on mobile * Re-order paragraphs * Sync paragraphs with their index * Add one more grey block * Fix scroll to top * better offset * Reformat code * Add social paragraph * Better word * Font tuning * More font/offset tuning * Increase navbar padding * Basic minify & livereload via gulp * Add styles to default in gulp * Do not minify html in reference * Add og:image header * "build" gulp target * Add readme for website * Max-width for navbar * Use different placeholder * Tune some margins * Do not center buttons * Tune navbar padding * s/an/a/ * Larger font at logo * Increase padding at hero * Yet another placeholder + tune padding on buttons * Basic support for website inside Docker * Listen for IPv6 inside Docker * s/available/enabled/g * nginx tuning * add gzip_min_length * not so dark "fork me" badge * do not commit build results * move "fork me" to right side * Tune styles and texts * tune mobile version * text fix * text fix * text fix * publish presentations * fix navbar styling * fix id name * Support actual deployment to either prod and test * tune logo margin * Mention ClickHouse Docker images * style tuning * disable mix-blend-mode on mobile * copy robots.txt
4
.gitignore
vendored
@ -223,3 +223,7 @@ config-preprocessed.xml
|
||||
|
||||
# Ignore symlink to private repository
|
||||
/private
|
||||
|
||||
# Gulp dependencies used to minify website
|
||||
node_modules
|
||||
public
|
||||
|
BIN
doc/favicon.ico
Before Width: | Height: | Size: 318 B |
@ -1,2 +0,0 @@
|
||||
User-agent: *
|
||||
Allow: /
|
4
website/Dockerfile
Normal file
@ -0,0 +1,4 @@
|
||||
FROM nginx:mainline
|
||||
COPY public /usr/share/nginx/html
|
||||
COPY nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
|
4
website/README.md
Executable file
@ -0,0 +1,4 @@
|
||||
ClickHouse website quickstart:
|
||||
1. If npm is not installed: `apt-get install npm` for Debian/Ubuntu, `brew install npm` for Mac OS or download and install manually https://nodejs.org/en/download/
|
||||
2. Run setup\_gulp.sh once to install prerequisites via npm
|
||||
3. Use `gulp build` to minify website to "public" folder or just `gulp` to run local webserver with livereload serving it
|
@ -2116,7 +2116,7 @@ try { var yaCounter18343495 = new Ya.Metrika({id:18343495,
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/18343495" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
|
||||
<script type="text/javascript" src="https://yandex.st/jquery/1.7.2/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="https://yastatic.net/jquery/3.1.1/jquery.min.js"></script>
|
||||
|
||||
<div class='island'>
|
||||
|
BIN
website/favicon.ico
Normal file
After Width: | Height: | Size: 171 B |
95
website/gulpfile.js
Normal file
@ -0,0 +1,95 @@
|
||||
var gulp = require('gulp');
|
||||
var concat = require('gulp-concat');
|
||||
var uglify = require('gulp-uglify');
|
||||
var cleanCss = require('gulp-clean-css');
|
||||
var imagemin = require('gulp-imagemin');
|
||||
var sourcemaps = require('gulp-sourcemaps');
|
||||
var htmlmin = require('gulp-htmlmin');
|
||||
var minifyInline = require('gulp-minify-inline');
|
||||
var del = require('del');
|
||||
var connect = require('gulp-connect');
|
||||
|
||||
var outputDir = 'public';
|
||||
|
||||
var paths = {
|
||||
htmls: ['*.html', '!reference_ru.html', '!reference_en.html'],
|
||||
reference: ['reference_ru.html', 'reference_en.html'],
|
||||
scripts: ['*.js', '!gulpfile.js'],
|
||||
styles: ['*.css'],
|
||||
images: ['*.png', '*.ico'],
|
||||
robotstxt: ['robots.txt'],
|
||||
presentations: ['../doc/presentations/**']
|
||||
};
|
||||
|
||||
gulp.task('clean', function () {
|
||||
return del([outputDir + '**']);
|
||||
});
|
||||
|
||||
gulp.task('reference', [], function () {
|
||||
return gulp.src(paths.reference)
|
||||
.pipe(minifyInline())
|
||||
.pipe(gulp.dest(outputDir))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('presentations', [], function () {
|
||||
return gulp.src(paths.presentations)
|
||||
.pipe(gulp.dest(outputDir + '/presentations'))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('robotstxt', [], function () {
|
||||
return gulp.src(paths.robotstxt)
|
||||
.pipe(gulp.dest(outputDir))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('htmls', ['reference', 'robotstxt', 'presentations'], function () {
|
||||
return gulp.src(paths.htmls)
|
||||
.pipe(htmlmin({collapseWhitespace: true}))
|
||||
.pipe(minifyInline())
|
||||
.pipe(gulp.dest(outputDir))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('scripts', [], function () {
|
||||
return gulp.src(paths.scripts)
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(uglify())
|
||||
.pipe(sourcemaps.write())
|
||||
.pipe(gulp.dest(outputDir))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('styles', [], function () {
|
||||
return gulp.src(paths.styles)
|
||||
.pipe(cleanCss())
|
||||
.pipe(gulp.dest(outputDir))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('images', [], function () {
|
||||
return gulp.src(paths.images)
|
||||
.pipe(imagemin({optimizationLevel: 9}))
|
||||
.pipe(gulp.dest(outputDir))
|
||||
.pipe(connect.reload())
|
||||
});
|
||||
|
||||
gulp.task('watch', function () {
|
||||
gulp.watch(paths.htmls, ['htmls']);
|
||||
gulp.watch(paths.scripts, ['scripts']);
|
||||
gulp.watch(paths.images, ['images']);
|
||||
});
|
||||
|
||||
gulp.task('connect', function() {
|
||||
connect.server({
|
||||
root: outputDir,
|
||||
port: 8080,
|
||||
keepalive: true,
|
||||
livereload: true
|
||||
})
|
||||
});
|
||||
|
||||
gulp.task('build', ['htmls', 'scripts', 'styles', 'images']);
|
||||
|
||||
gulp.task('default', ['build', 'watch', 'connect']);
|
884
website/index.html
Normal file
@ -0,0 +1,884 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
|
||||
<title>ClickHouse — open source distributed column-oriented DBMS</title>
|
||||
|
||||
<link rel="shortcut icon" href="favicon.ico"/>
|
||||
|
||||
<meta property="og:title" content="ClickHouse DBMS"/>
|
||||
<meta property="og:description"
|
||||
content="ClickHouse is an open source column-oriented database management system that allows generating analytical data reports in real time using SQL queries."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:url" content="https://clickhouse.yandex"/>
|
||||
<meta property="og:image" content="https://clickhouse.yandex/logo.png"/>
|
||||
|
||||
<meta property="twitter:title" content="ClickHouse DBMS"/>
|
||||
|
||||
<meta name="description"
|
||||
content="ClickHouse is an open source distributed column-oriented database management system that allows generating analytical data reports in real time using SQL queries. Сreated by Yandex ClickHouse manages extremely large volumes of data in a stable and sustainable manner."/>
|
||||
<meta name="keywords"
|
||||
content="ClickHouse, DBMS, OLAP, relational, analytics, analytical, big data, open-source, SQL, web-analytics" />
|
||||
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Text Web';
|
||||
src: url(https://yastatic.net/adv-www/_/yy5JveR58JFkc97waf-xp0i6_jM.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/yy5JveR58JFkc97waf-xp0i6_jM.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/CYblzLEXzCqQIvrYs7QKQe2omRk.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/pUcnOdRwl83MvPPzrNomhyletnA.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/vNFEmXOcGYKJ4AAidUprHWoXrLU.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/0w7OcWZM_QLP8x-LQUXFOgXO6dE.svg#YandexSansTextWeb-Bold) format('svg');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Text Web';
|
||||
src: url(https://yastatic.net/adv-www/_/LI6l3L2RqcgxBe2pXmuUha37czQ.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/LI6l3L2RqcgxBe2pXmuUha37czQ.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/z3MYElcut0R2MF_Iw1RDNrstgYs.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/1jvKJ_-hCXl3s7gmFl-y_-UHTaI.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/9nzjfpCR2QHvK1EzHpDEIoVFGuY.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/gwyBTpxSwkFCF1looxqs6JokKls.svg#YandexSansTextWeb-Regular) format('svg');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Text Web';
|
||||
src: url(https://yastatic.net/adv-www/_/ayAFYoY8swgBLhq_I56tKj2JftU.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/ayAFYoY8swgBLhq_I56tKj2JftU.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/lGQcYklLVV0hyvz1HFmFsUTj8_0.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/f0AAJ9GJ4iiwEmhG-7PWMHk6vUY.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/4UDe4nlVvgEJ-VmLWNVq3SxCsA.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/EKLr1STNokPqxLAQa_RyN82pL98.svg#YandexSansTextWeb-Light) format('svg');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Display Web';
|
||||
src: url(https://yastatic.net/adv-www/_/H63jN0veW07XQUIA2317lr9UIm8.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/H63jN0veW07XQUIA2317lr9UIm8.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/sUYVCPUAQE7ExrvMS7FoISoO83s.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/v2Sve_obH3rKm6rKrtSQpf-eB7U.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/PzD8hWLMunow5i3RfJ6WQJAL7aI.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/lF_KG5g4tpQNlYIgA0e77fBSZ5s.svg#YandexSansDisplayWeb-Regular) format('svg');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Display Web';
|
||||
src: url(https://yastatic.net/adv-www/_/g8_MyyKVquSZ3xEL6tarK__V9Vw.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/g8_MyyKVquSZ3xEL6tarK__V9Vw.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/LGiRvlfqQHlWR9YKLhsw5e7KGNA.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/40vXwNl4eYYMgteIVgLP49dwmfc.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/X6zG5x_wO8-AtwJ-vDLJcKC5228.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/ZKhaR0m08c8CRRL77GtFKoHcLYA.svg#YandexSansDisplayWeb-Light) format('svg');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font: 300 14pt/200% 'Yandex Sans Text Web', Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #efefef;
|
||||
padding: 6px 0 0 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#navbar-inner {
|
||||
max-width: 1280px;
|
||||
margin: 4px auto;
|
||||
}
|
||||
|
||||
#logo {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
#main-title {
|
||||
font: 400 42pt/90% 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#title-logo {
|
||||
margin: 1px 8px 0 13px;
|
||||
}
|
||||
|
||||
#github {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
font-size: 85%;
|
||||
font-weight: 400;
|
||||
padding: 0 4em;
|
||||
margin: 0 -4em 2.5em 0;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-ms-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
background: #fc0;
|
||||
border: 2px solid #000;
|
||||
mix-blend-mode: hard-light;
|
||||
}
|
||||
|
||||
#github_link {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#github_link:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.page {
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 47px 0 23px;
|
||||
font: 400 200%/133% 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.smaller-font {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #08f;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #f00;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#top-menu {
|
||||
margin: 12px 0 0 0;
|
||||
font: 400 18pt 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.menu_item:link,
|
||||
.menu_item:active,
|
||||
.menu_item:visited {
|
||||
margin: 0 8px 0 0;
|
||||
padding: 5px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.menu_item:hover, .index_item:hover {
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 2px solid #fc0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.index_item:link,
|
||||
.index_item:active,
|
||||
.index_item:visited {
|
||||
color: #ededed;
|
||||
font: 300 100% 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
}
|
||||
|
||||
#short-description {
|
||||
font: 300 125%/150% 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
margin: 0 1em 1.75em 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#hero {
|
||||
background: #555;
|
||||
padding: 110px 0 40px 0;
|
||||
color: #ededed;
|
||||
}
|
||||
|
||||
#index_ul {
|
||||
margin-top: 2px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
#slogan {
|
||||
}
|
||||
|
||||
#placeholder {
|
||||
width: 66%;
|
||||
margin: 5% auto 0 auto;
|
||||
}
|
||||
|
||||
.colored-block {
|
||||
width: 100%;
|
||||
padding: 20px 0 60px 0;
|
||||
margin: 60px 0;
|
||||
}
|
||||
|
||||
.colored-block>h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#performance {
|
||||
background: #fc0;
|
||||
}
|
||||
|
||||
#call_to_action, #benchmark_learn_more {
|
||||
text-decoration: none;
|
||||
padding-left: 18px;
|
||||
font-size: 120%;
|
||||
width: 182px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#call_to_action {
|
||||
background: url('yandex-white-button.png') no-repeat;
|
||||
color: #ededed;
|
||||
}
|
||||
|
||||
#call_to_action:hover {
|
||||
color: #fc0;
|
||||
}
|
||||
|
||||
#benchmark_learn_more {
|
||||
background: url('yandex-black-button.png') no-repeat;
|
||||
float: right;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#grey-block {
|
||||
background: #555;
|
||||
color: #ededed;
|
||||
}
|
||||
|
||||
#ubuntu-install {
|
||||
overflow: auto;
|
||||
overflow-y: hidden;
|
||||
-ms-overflow-y: hidden;
|
||||
}
|
||||
|
||||
#footer {
|
||||
text-align: right;
|
||||
padding: 8px 0 0 0;
|
||||
color: #888;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
code {
|
||||
font: 13px/18px monospace, "Courier New";
|
||||
display: block;
|
||||
border-left: 5px solid #ffdb4d;
|
||||
padding: 5px 10px;
|
||||
background: #000;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
ul.dashed {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
ul.dashed > li {
|
||||
text-indent: 15px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
ul.dashed > li:before {
|
||||
content: '— ';
|
||||
text-indent: 1em;
|
||||
}
|
||||
|
||||
.warranty {
|
||||
margin-top: 6em;
|
||||
font-size: 50%;
|
||||
color: #888;
|
||||
line-height: 150%;
|
||||
border-top: 1px solid #888;
|
||||
padding: 1em 0;
|
||||
}
|
||||
|
||||
.distributive_selected {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.distributive_not_selected {
|
||||
color: #08f;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #08f;
|
||||
}
|
||||
|
||||
.block-50 {
|
||||
float: left;
|
||||
display: block;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.block-30 {
|
||||
float: left;
|
||||
display: block;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.block-70 {
|
||||
float: left;
|
||||
display: block;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.orange {
|
||||
fill: #fc0;
|
||||
color: #fc0;
|
||||
}
|
||||
|
||||
.red {
|
||||
fill: #f00;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
body {
|
||||
font-size: 18pt;
|
||||
}
|
||||
|
||||
#index_ul {
|
||||
padding-left: 0;
|
||||
margin: 0 0 30px -16px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
#hero {
|
||||
padding: 40px 0 10px 0;
|
||||
}
|
||||
|
||||
.desktop-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.smaller-font {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin: 1.33em 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#hero ul.dashed > li:before {
|
||||
content: '';
|
||||
}
|
||||
|
||||
#hero .index_item {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
#hero .dashed {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
#call_to_action {
|
||||
margin: 20px 0 40px 0;
|
||||
}
|
||||
|
||||
#short-description {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
#github {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
font-size: 110%;
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-ms-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
background: #fc0;
|
||||
border: 0;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
|
||||
#benchmark_learn_more, #call_to_action {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.block-30, .block-50, .block-70 {
|
||||
width: 100%;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="navbar">
|
||||
<div id="navbar-inner">
|
||||
<div id="top-menu" class="desktop-only">
|
||||
<a class="menu_item" href="#quick-start">Quick Start</a>
|
||||
<a class="menu_item" href="#performance">Performance</a>
|
||||
<a class="menu_item" href="reference_en.html">Documentation</a>
|
||||
<a class="menu_item" href="#contacts">Contacts</a>
|
||||
</div>
|
||||
|
||||
<a id="logo" href="#">
|
||||
<h1 id="main-title">
|
||||
<svg id="title-logo" xmlns="http://www.w3.org/2000/svg" width="48" height="44" viewBox="0 0 9 8">
|
||||
<path class="red" d="M0,7 h1 v1 h-1 z"></path>
|
||||
<path class="orange" d="M0,0 h1 v7 h-1 z"></path>
|
||||
<path class="orange" d="M2,0 h1 v8 h-1 z"></path>
|
||||
<path class="orange" d="M4,0 h1 v8 h-1 z"></path>
|
||||
<path class="orange" d="M6,0 h1 v8 h-1 z"></path>
|
||||
<path class="orange" d="M8,3.25 h1 v1.5 h-1 z"></path>
|
||||
</svg>
|
||||
|
||||
ClickHouse
|
||||
</h1>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="hero">
|
||||
<div class="page">
|
||||
<div class="block-70">
|
||||
<p id="short-description">ClickHouse is an <span class="orange">open source</span> column-oriented
|
||||
database management system
|
||||
capable of <span class="orange">real time</span> generation of analytical data reports using <span
|
||||
class="orange">SQL</span> queries.</p>
|
||||
<a id="call_to_action" href="#quick-start">
|
||||
Quick Start
|
||||
</a>
|
||||
</div>
|
||||
<div class="block-30">
|
||||
<ul id="index_ul" class="dashed">
|
||||
<li>
|
||||
<a class="index_item" href="#blazing-fast">Blazing Fast</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="index_item" href="#linearly-scalable">Linearly Scalable</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="index_item" href="#hardware-efficient">Hardware Efficient</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="index_item" href="#fault-tolerant">Fault Tolerant</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="index_item" href="#feature-rich">Feature Rich</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="index_item" href="#simple-and-handy">Simple and Handy</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="index_item" href="#highly-reliable">Highly Reliable</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<a id="github_link"
|
||||
href="https://github.com/yandex/ClickHouse"
|
||||
rel="external nofollow"
|
||||
target="_blank"
|
||||
><div id="github">Fork me on GitHub</div></a>
|
||||
|
||||
<div class="page">
|
||||
<h2 id="slogan">ClickHouse. Just makes you think faster.</h2>
|
||||
|
||||
<div class="block-70">
|
||||
<ul class="dashed">
|
||||
<li>Run more queries in the same amount of time</li>
|
||||
<li>Test more hypotheses</li>
|
||||
<li>Slice and dice your data in many more new ways</li>
|
||||
<li>Look at your data from new angles</li>
|
||||
<li>Discover new dimensions</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="block-30">
|
||||
<svg id="placeholder" class="desktop-only" viewBox="0 0 76 76" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="16" width="60" height="60" rx="1"></rect>
|
||||
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="60" height="60" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<rect id="path-3" x="16" y="0" width="60" height="60" rx="1"></rect>
|
||||
<mask id="mask-4" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="60" height="60" fill="white">
|
||||
<use xlink:href="#path-3"></use>
|
||||
</mask>
|
||||
<rect id="path-5" x="0" y="8" width="20" height="20" rx="1"></rect>
|
||||
<mask id="mask-6" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="20" height="20" fill="white">
|
||||
<use xlink:href="#path-5"></use>
|
||||
</mask>
|
||||
<rect id="path-7" x="8" y="0" width="20" height="20" rx="1"></rect>
|
||||
<mask id="mask-8" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="20" height="20" fill="white">
|
||||
<use xlink:href="#path-7"></use>
|
||||
</mask>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
|
||||
<g id="Clickhouse_2" transform="translate(-558.000000, -1293.000000)">
|
||||
<g id="Group-11" transform="translate(558.000000, 1293.000000)">
|
||||
<use id="Rectangle-33" stroke="#FFCC00" mask="url(#mask-2)" stroke-width="4" xlink:href="#path-1"></use>
|
||||
<use id="Rectangle-33" stroke="#FFCC00" mask="url(#mask-4)" stroke-width="4" xlink:href="#path-3"></use>
|
||||
<path d="M0.989013672,17.017334 L16.8210449,1.16748047" id="Path-26" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M59.0788574,74.9973145 L74.7983398,59.2650146" id="Path-26" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M59.1091309,17.1687012 L74.9368896,1.10351562" id="Path-26-Copy" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M1.07910156,17.2504883 L26.0395508,33.4033203" id="Path-26" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M17.2602539,1.18457031 L34.0175781,25.1796875" id="Path-26" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M51.2958984,25.4736328 L58.8277588,17" id="Path-26-Copy" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M1.01904297,50.942627 L25.9216309,75.064209" id="Path-26" stroke="#FFCC00" stroke-width="2" transform="translate(13.470337, 63.003418) scale(-1, 1) translate(-13.470337, -63.003418) "></path>
|
||||
<path d="M44.1804199,51.300293 L58.9638672,75.010498" id="Path-26" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<path d="M52.0131836,43.1345215 L75.0227051,58.9299316" id="Path-26" stroke="#FFCC00" stroke-width="2"></path>
|
||||
<g id="Group-3" transform="translate(25.000000, 24.000000)" stroke="#444444">
|
||||
<use id="Rectangle-33" mask="url(#mask-6)" stroke-width="4" xlink:href="#path-5"></use>
|
||||
<use id="Rectangle-33" mask="url(#mask-8)" stroke-width="4" xlink:href="#path-7"></use>
|
||||
<path d="M19.2587891,1.08825684 L26.7729492,8.8046875" id="Path-26" stroke-width="2" transform="translate(23.015869, 4.946472) scale(-1, 1) translate(-23.015869, -4.946472) "></path>
|
||||
<path d="M1.05773926,1.04125977 L8.82080078,8.9654541" id="Path-26" stroke-width="2" transform="translate(4.939270, 5.003357) scale(-1, 1) translate(-4.939270, -5.003357) "></path>
|
||||
<path d="M1.12487793,18.887207 L9.26220703,26.8897705" id="Path-26" stroke-width="2" transform="translate(5.193542, 22.888489) scale(-1, 1) translate(-5.193542, -22.888489) "></path>
|
||||
<path d="M19.038208,19.1968994 L26.9085693,26.9760742" id="Path-26" stroke-width="2" transform="translate(22.973389, 23.086487) scale(-1, 1) translate(-22.973389, -23.086487) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
|
||||
|
||||
<h2 id="blazing-fast">Blazing Fast</h2>
|
||||
|
||||
<p>ClickHouse's performance <a href="benchmark.html">exceeds</a> comparable column-oriented DBMS currently available
|
||||
on the market. It processes hundreds of millions to more than a billion rows and tens of gigabytes of data
|
||||
per single server per second.</p>
|
||||
|
||||
<p>ClickHouse uses all available hardware to its full potential to process each query as fast as possible. The peak
|
||||
processing performance for a single query (after decompression, only used columns) stands at more than 2 terabytes
|
||||
per second.</p>
|
||||
</div>
|
||||
<div id="performance" class="colored-block">
|
||||
<div class="page">
|
||||
<h2>ClickHouse works 100-1,000x faster than traditional approaches</h2>
|
||||
<p>In contrast to data management methods, where vast amounts of raw data in its native format are available as
|
||||
a "data lake" for any
|
||||
given query, ClickHouse, in most cases, offers instant results: the data is processed faster than it takes
|
||||
to make a query. Follow the link to see detailed benchmarks in comparison with other database management
|
||||
systems.</p>
|
||||
<a id="benchmark_learn_more" href="benchmark.html">
|
||||
Learn more
|
||||
</a>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page">
|
||||
<h2 id="linearly-scalable">Linearly Scalable</h2>
|
||||
|
||||
<p>ClickHouse allows companies to add servers to their clusters when necessary without investing time or money into
|
||||
additional DBMS modification. The system has been successfully serving <a href="https://metrica.yandex.com/">Yandex.Metrica</a>,
|
||||
while the servers just in its main cluster, located in six geographically distributed datacenters, have grown
|
||||
from 60 to 394 in two years.</p>
|
||||
|
||||
<p>ClickHouse scales well both vertically and horizontally. ClickHouse is easily adaptable to perform both on
|
||||
hundreds of node clusters, and on a single server or even virtual machine. It currently has installations
|
||||
with more than two trillion rows per single node, as well as installations with 100 TB of storage per single
|
||||
node.</p>
|
||||
|
||||
|
||||
<h2 id="hardware-efficient">Hardware Efficient</h2>
|
||||
|
||||
<p>ClickHouse processes typical analytical queries two to three orders of magnitude faster than traditional
|
||||
row-oriented systems with the same available IO throughput. The system’s columnar format allows fitting more hot
|
||||
data in the server’s RAM, which leads to a shorter response time.</p>
|
||||
|
||||
<p>ClickHouse allows to minimize number of seeks for range queries, which increases efficiency of using rotational
|
||||
drives, as it maintains locality of reference for stored data continually.</p>
|
||||
|
||||
<p>ClickHouse is CPU efficient because of its vectorized query execution and runtime code generation.</p>
|
||||
|
||||
<p>By minimizing data transfers for most types of queries, ClickHouse enables companies to manage their data and
|
||||
create reports without using a network that supports high-performance computing.</p>
|
||||
</div>
|
||||
<div id="grey-block" class="colored-block">
|
||||
<div class="page">
|
||||
<h2 id="fault-tolerant">Fault Tolerant</h2>
|
||||
|
||||
<p>ClickHouse supports multi-master asynchronous replication and can be deployed across multiple datacenters.
|
||||
Downtime of a single node or the whole datacenter won’t affect the system’s availability for reads and
|
||||
writes.
|
||||
Distributed reads are automatically balanced to live replicas without increasing latency. Replicated data
|
||||
are
|
||||
synchronized automatically or semi-automatically after the downtime.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page">
|
||||
|
||||
<h2 id="feature-rich">Feature Rich</h2>
|
||||
|
||||
<p>ClickHouse features a number of built-in user-friendly web analytics capabilities, including probabilistic data
|
||||
structures for fast and memory-efficient calculation of cardinalities and quantiles, or functions for addressing
|
||||
URLs and IPs (both IPv4 and IPv6) as well as identifying dates, times and time zones.</p>
|
||||
|
||||
<p>Data management methods available in ClickHouse, such as arrays, array joins and nested data structures, are
|
||||
extremely efficient for managing denormalized data.</p>
|
||||
|
||||
<p>Using ClickHouse allows joining both distributed data and co-located data, as the system supports local joins and
|
||||
distributed joins. It also offers an opportunity to use external dictionaries, dimension tables loaded from
|
||||
an external source, for seamless joins.</p>
|
||||
|
||||
<p>ClickHouse supports approximate query processing – you can get results as fast as you want, which is
|
||||
indispensable when dealing with terabytes and petabytes of data.</p>
|
||||
|
||||
<p>The system’s conditional aggregate functions, calculation of totals and extremes, allow getting results with a
|
||||
single query without having to run a number of them.</p>
|
||||
|
||||
<div class="block-50">
|
||||
<h2>Key Features</h2>
|
||||
|
||||
<ul class="dashed smaller-font">
|
||||
<li>True column-oriented storage</li>
|
||||
<li>Vectorized query execution</li>
|
||||
<li>Data compression</li>
|
||||
<li>Parallel and distributed query execution</li>
|
||||
<li>Real-time query processing and data ingestion</li>
|
||||
<li>On-disk locality of reference</li>
|
||||
<li>Cross-datacenter replication</li>
|
||||
<li>High availability</li>
|
||||
<li>SQL support</li>
|
||||
<li>Local and distributed joins</li>
|
||||
<li>Pluggable external dimension tables</li>
|
||||
<li>Arrays and nested data types</li>
|
||||
<li>Approximate query processing</li>
|
||||
<li>Probabilistic data structures</li>
|
||||
<li>Full support of IPv6</li>
|
||||
<li>Features for web analytics</li>
|
||||
<li>State-of-the-art algorithms</li>
|
||||
<li>Detailed documentation</li>
|
||||
<li>Clean documented code</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="block-50">
|
||||
<h2>Applications</h2>
|
||||
|
||||
<ul class="dashed smaller-font">
|
||||
<li>Web and App analytics</li>
|
||||
<li>Advertising networks and RTB</li>
|
||||
<li>Telecommunications</li>
|
||||
<li>E-commerce</li>
|
||||
<li>Information security</li>
|
||||
<li>Monitoring and telemetry</li>
|
||||
<li>Business intelligence</li>
|
||||
<li>Online games</li>
|
||||
<li>Internet of Things</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<h2 id="simple-and-handy">Simple and Handy</h2>
|
||||
<p>ClickHouse streamlines all your data processing. It’s easy to use: ingest all your structured data into the
|
||||
system, and it is instantly available for reports. New columns for new properties or dimensions can be
|
||||
easily added to the system at any time without slowing it down.</p>
|
||||
|
||||
|
||||
<p>ClickHouse is simple and works out-of-the-box. As well as performing on hundreds of node clusters, this system
|
||||
can be easily installed on a single server or even a virtual machine. No development experience or code-writing
|
||||
skills are required to install ClickHouse.</p>
|
||||
|
||||
<h2 id="highly-reliable">Highly Reliable</h2>
|
||||
|
||||
<p>ClickHouse has been managing petabytes of data serving a number of highload mass audience services of Russia’s
|
||||
leading search provider and one of Europe’s largest IT companies, <a href="https://www.yandex.com/company/"
|
||||
rel="external nofollow">Yandex</a>.
|
||||
Since 2012, ClickHouse has been providing robust database management for the company’s <a
|
||||
href="https://metrica.yandex.com/" rel="external nofollow">web analytics service</a>, comparison
|
||||
shopping platform, email
|
||||
service, online advertising platform, business intelligence and infrastructure monitoring.</p>
|
||||
|
||||
<p>ClickHouse is purely distributed system located on independent nodes, which has no single point of failure.</p>
|
||||
|
||||
<p>Software or hardware failures or misconfigurations do not result in loss of data. Instead of deleting "broken"
|
||||
data, ClickHouse saves it or asks you what to do before a startup. All data are checksummed before every
|
||||
read or write to disk or network. It is virtually impossible to delete data by accident.</p>
|
||||
|
||||
<p>ClickHouse offers flexible limits on query complexity and resource usage, which can be fine-tuned using settings.
|
||||
It is possible to simultaneously serve both a number of high priority low-latency requests and some
|
||||
long-running queries with lowered priority.</p>
|
||||
|
||||
<h2>Use Cases</h2>
|
||||
|
||||
<p>ClickHouse currently powers
|
||||
<a href="https://metrica.yandex.com/" rel="external nofollow">Yandex.Metrica</a>, world's <a
|
||||
href="http://w3techs.com/technologies/overview/traffic_analysis/all" rel="external nofollow">second
|
||||
largest</a> web analytics
|
||||
platform, with over 13 trillion database records and over 20 billion events a day, generating customized
|
||||
reports on the fly directly from non-aggregated data.</p>
|
||||
<p>Another example is <a
|
||||
href="https://www.yandex.com/company/press_center/press_releases/2012/2012-04-10/"
|
||||
rel="external nofollow">CERN’s LHCb experiment</a>
|
||||
to store and process metadata on 10bn events with over 1000 attributes per event registered
|
||||
in 2011.</p>
|
||||
|
||||
<h2 id="quick-start">Quick Start</h2>
|
||||
|
||||
<p>System requirements: Linux, x86_64 with SSE 4.2.</p>
|
||||
|
||||
<p>Install packages for
|
||||
<span class="distributive_not_selected" id="ubuntu_xenial">Ubuntu 16.04 Xenial</span>, <span
|
||||
class="distributive_selected" id="ubuntu_trusty">Ubuntu 14.04 Trusty</span> or <span
|
||||
class="distributive_not_selected" id="ubuntu_precise">Ubuntu 12.04 Precise</span>:
|
||||
</p>
|
||||
|
||||
<code id="ubuntu-install">
|
||||
<pre>
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4 # optional
|
||||
|
||||
sudo mkdir -p /etc/apt/sources.list.d
|
||||
echo "deb http://repo.yandex.ru/clickhouse/<span id="distributive">trusty</span> stable main" |
|
||||
sudo tee /etc/apt/sources.list.d/clickhouse.list
|
||||
sudo apt-get update
|
||||
|
||||
sudo apt-get install clickhouse-server-common clickhouse-client
|
||||
|
||||
sudo service clickhouse-server start
|
||||
clickhouse-client
|
||||
</pre>
|
||||
</code>
|
||||
|
||||
<p>For other operating systems the easiest way to get started is using
|
||||
<a href="https://hub.docker.com/r/yandex/clickhouse-server/" rel="external nofollow"
|
||||
target="_blank">
|
||||
official Docker images of ClickHouse</a>
|
||||
. Alternatively you can build ClickHouse from <a
|
||||
href="https://github.com/yandex/ClickHouse" rel="external nofollow"
|
||||
target="_blank">sources</a>
|
||||
according to the <a
|
||||
href="https://github.com/yandex/ClickHouse/blob/master/doc/build.md" rel="external nofollow"
|
||||
target="_blank">instruction</a>.</p>
|
||||
|
||||
<p>After installation proceed to <strong><a href="tutorial.html">tutorial</a></strong> or <strong><a href="reference_en.html">full
|
||||
documentation</a></strong>.</p>
|
||||
|
||||
|
||||
<h2 id="contacts">Contacts</h2>
|
||||
<ul class="dashed">
|
||||
<li>Ask any questions on <a href="https://stackoverflow.com/questions/tagged/clickhouse"
|
||||
rel="external nofollow">Stack Overflow</a>.
|
||||
</li>
|
||||
<li>Discuss with real users in Telegram chat in <a href="https://telegram.me/clickhouse_en"
|
||||
rel="external nofollow">English</a> or in <a
|
||||
href="https://telegram.me/clickhouse_ru" rel="external nofollow">Russian</a>.
|
||||
</li>
|
||||
<li>Use <a href="https://groups.google.com/group/clickhouse" rel="external nofollow">Google Group</a> for
|
||||
discussion.
|
||||
</li>
|
||||
<li>Or email ClickHouse team at Yandex:
|
||||
<a id="feedback_email" href="">turn on JavaScript to see email address</a>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Like ClickHouse?</h2>
|
||||
<p>Help to spread the word about it via <a rel="external nofollow" target="_blank" href="https://www.facebook.com/sharer.php?u=https://clickhouse.yandex">Facebook</a>,
|
||||
<a rel="external nofollow" target="_blank" href="https://twitter.com/intent/tweet?url=https://clickhouse.yandex">Twitter</a> and
|
||||
<a rel="external nofollow" target="_blank" href="https://www.linkedin.com/shareArticle?url=https://clickhouse.yandex">LinkedIn</a>!</p>
|
||||
|
||||
|
||||
<p class="warranty">Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied.</p>
|
||||
|
||||
<p id="footer">© 2016–2017 <a href="https://yandex.com/company/" rel="external nofollow">YANDEX</a> LLC</p>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="https://yastatic.net/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
var name = $('#main-title').text().trim().toLowerCase();
|
||||
var feedback_address = name + '-feedback' + '@yandex-team.com';
|
||||
var feedback_email = $('#feedback_email');
|
||||
feedback_email.attr('href', 'mailto:' + feedback_address);
|
||||
feedback_email.html(feedback_address);
|
||||
|
||||
$("a[href^='#']").on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var selector = $(e.target).attr('href');
|
||||
var offset = 0;
|
||||
|
||||
if (selector) {
|
||||
offset = $(selector).offset().top - $('#logo').height() * 1.5;
|
||||
}
|
||||
$('html, body').animate({
|
||||
scrollTop: offset
|
||||
}, 500);
|
||||
});
|
||||
|
||||
var available_distributives = ['xenial', 'trusty', 'precise'];
|
||||
available_distributives.forEach(function (name) {
|
||||
$('#ubuntu_' + name).on('click', function () {
|
||||
$('#distributive').html(name);
|
||||
available_distributives.forEach(function (distr) {
|
||||
$('#ubuntu_' + distr).attr('class', (name == distr) ? 'distributive_selected' : 'distributive_not_selected');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script src="https://mc.yandex.ru/metrika/watch.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var yaCounter18343495 = new Ya.Metrika({
|
||||
id: 18343495,
|
||||
webvisor: true,
|
||||
clickmap: true,
|
||||
trackLinks: true,
|
||||
accurateTrackBounce: true,
|
||||
trackHash: true
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
</script>
|
||||
<noscript>
|
||||
<div><img src="https://mc.yandex.ru/watch/18343495" style="position:absolute; left:-9999px;" alt=""/></div>
|
||||
</noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
</body>
|
||||
</html>
|
10220
website/jquery.js
vendored
Normal file
BIN
website/logo.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
21
website/nginx/default.conf
Normal file
@ -0,0 +1,21 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80 default ipv6only=on;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
#error_page 500 502 503 504 /50x.html;
|
||||
#location = /50x.html {
|
||||
# root /usr/share/nginx/www;
|
||||
#}
|
||||
|
||||
}
|
37
website/nginx/nginx.conf
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 4096;
|
||||
multi_accept on;
|
||||
use epoll;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
gzip on;
|
||||
gzip_comp_level 5;
|
||||
gzip_min_length 256;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
}
|
@ -220,3 +220,10 @@ a:hover
|
||||
.c13 { color: #ff54ff; }
|
||||
.c14 { color: #54ffff; }
|
||||
.c15 { color: #fff; }
|
||||
|
||||
.orange {
|
||||
fill: #fc0;
|
||||
}
|
||||
.red {
|
||||
fill: #f00
|
||||
}
|
34
website/release.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
BASE_DIR=$(dirname $(readlink -f $0))
|
||||
cd "${BASE_DIR}"
|
||||
gulp build
|
||||
IMAGE="clickhouse/website"
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
TAG=$(head -c 8 /dev/urandom | xxd -p)
|
||||
else
|
||||
TAG="$1"
|
||||
fi
|
||||
FULL_NAME="${IMAGE}:${TAG}"
|
||||
REMOTE_NAME="registry.yandex.net/${FULL_NAME}"
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
docker build -t "${FULL_NAME}" "${BASE_DIR}"
|
||||
docker tag "${FULL_NAME}" "${REMOTE_NAME}"
|
||||
docker push "${REMOTE_NAME}"
|
||||
fi
|
||||
|
||||
QLOUD_ENDPOINT="https://platform.yandex-team.ru/api/v1"
|
||||
QLOUD_PROJECT="clickhouse.clickhouse-website"
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
QLOUD_ENV="${QLOUD_PROJECT}.test"
|
||||
else
|
||||
QLOUD_ENV="${QLOUD_PROJECT}.prod"
|
||||
fi
|
||||
QLOUD_COMPONENT="${QLOUD_ENV}.nginx"
|
||||
QLOUD_VERSION=$(curl -v -H "Authorization: OAuth ${QLOUD_TOKEN}" "${QLOUD_ENDPOINT}/environment/status/${QLOUD_ENV}" | python -c "import json; import sys; print json.loads(sys.stdin.read()).get('version')")
|
||||
curl -v -H "Authorization: OAuth ${QLOUD_TOKEN}" -H "Content-Type: application/json" --data "{\"repository\": \"${REMOTE_NAME}\"}" "${QLOUD_ENDPOINT}/component/${QLOUD_COMPONENT}/${QLOUD_VERSION}/deploy" > /dev/null
|
||||
|
||||
echo ">>> Successfully deployed ${TAG} to ${QLOUD_ENV} <<<"
|
3
website/robots.txt
Normal file
@ -0,0 +1,3 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Host: https://clickhouse.yandex
|
3
website/setup_gulp.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
grep require gulpfile.js | awk -F\' '{print $2;}' | xargs npm install
|
830
website/tutorial.html
Normal file
@ -0,0 +1,830 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>ClickHouse — quick start guide</title>
|
||||
|
||||
<link rel="shortcut icon" href="favicon.ico"/>
|
||||
|
||||
<meta name="description" content="Quick start guide to ClickHouse — open-source distributed column-oriented DBMS"/>
|
||||
<meta name="keywords"
|
||||
content="ClickHouse, DBMS, OLAP, relational, analytics, analytical, big data, open-source, SQL, web-analytics"/>
|
||||
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Text Web';
|
||||
src: url(https://yastatic.net/adv-www/_/yy5JveR58JFkc97waf-xp0i6_jM.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/yy5JveR58JFkc97waf-xp0i6_jM.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/CYblzLEXzCqQIvrYs7QKQe2omRk.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/pUcnOdRwl83MvPPzrNomhyletnA.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/vNFEmXOcGYKJ4AAidUprHWoXrLU.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/0w7OcWZM_QLP8x-LQUXFOgXO6dE.svg#YandexSansTextWeb-Bold) format('svg');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Text Web';
|
||||
src: url(https://yastatic.net/adv-www/_/LI6l3L2RqcgxBe2pXmuUha37czQ.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/LI6l3L2RqcgxBe2pXmuUha37czQ.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/z3MYElcut0R2MF_Iw1RDNrstgYs.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/1jvKJ_-hCXl3s7gmFl-y_-UHTaI.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/9nzjfpCR2QHvK1EzHpDEIoVFGuY.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/gwyBTpxSwkFCF1looxqs6JokKls.svg#YandexSansTextWeb-Regular) format('svg');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Text Web';
|
||||
src: url(https://yastatic.net/adv-www/_/ayAFYoY8swgBLhq_I56tKj2JftU.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/ayAFYoY8swgBLhq_I56tKj2JftU.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/lGQcYklLVV0hyvz1HFmFsUTj8_0.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/f0AAJ9GJ4iiwEmhG-7PWMHk6vUY.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/4UDe4nlVvgEJ-VmLWNVq3SxCsA.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/EKLr1STNokPqxLAQa_RyN82pL98.svg#YandexSansTextWeb-Light) format('svg');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Display Web';
|
||||
src: url(https://yastatic.net/adv-www/_/H63jN0veW07XQUIA2317lr9UIm8.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/H63jN0veW07XQUIA2317lr9UIm8.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/sUYVCPUAQE7ExrvMS7FoISoO83s.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/v2Sve_obH3rKm6rKrtSQpf-eB7U.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/PzD8hWLMunow5i3RfJ6WQJAL7aI.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/lF_KG5g4tpQNlYIgA0e77fBSZ5s.svg#YandexSansDisplayWeb-Regular) format('svg');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Yandex Sans Display Web';
|
||||
src: url(https://yastatic.net/adv-www/_/g8_MyyKVquSZ3xEL6tarK__V9Vw.eot);
|
||||
src: url(https://yastatic.net/adv-www/_/g8_MyyKVquSZ3xEL6tarK__V9Vw.eot?#iefix) format('embedded-opentype'),
|
||||
url(https://yastatic.net/adv-www/_/LGiRvlfqQHlWR9YKLhsw5e7KGNA.woff2) format('woff2'),
|
||||
url(https://yastatic.net/adv-www/_/40vXwNl4eYYMgteIVgLP49dwmfc.woff) format('woff'),
|
||||
url(https://yastatic.net/adv-www/_/X6zG5x_wO8-AtwJ-vDLJcKC5228.ttf) format('truetype'),
|
||||
url(https://yastatic.net/adv-www/_/ZKhaR0m08c8CRRL77GtFKoHcLYA.svg#YandexSansDisplayWeb-Light) format('svg');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-stretch: normal
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font: 300 12pt/150% 'Yandex Sans Text Web', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 900px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
font-size: 100px;
|
||||
font-weight: normal;
|
||||
margin-top: 100px;
|
||||
margin-bottom: 0;
|
||||
text-align: center;
|
||||
padding-top: 27px;
|
||||
}
|
||||
|
||||
.title_link, .title_link:active, .title_link:visited, .title_link:link, .title_link:hover {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font: normal 50px 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
text-align: center;
|
||||
margin-top: 35px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font: normal 24px 'Yandex Sans Display Web', Arial, sans-serif;
|
||||
margin-top: 36px;
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: #08f;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: #f00;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: right;
|
||||
margin-top: 40px;
|
||||
border-top: 1px solid #EEE;
|
||||
padding: 10px 0 0;
|
||||
color: #888;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
pre {
|
||||
font: 13px/18px monospace, "Courier New";
|
||||
display: block;
|
||||
border-left: 5px solid #ffdb4d;
|
||||
padding: 5px 10px;
|
||||
background-color: #FFF8E8;
|
||||
}
|
||||
|
||||
.spoiler {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.spoiler_body {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spoiler_title {
|
||||
color: #08f;
|
||||
border-bottom: 1px dotted #08f;
|
||||
}
|
||||
|
||||
.spoiler_title:hover {
|
||||
cursor: pointer;
|
||||
color: #f00;
|
||||
border-bottom: 1px dashed #f00;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tip {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #EEE;
|
||||
padding: 5px 10px 5px 10px;
|
||||
}
|
||||
|
||||
.tip b {
|
||||
font-size: 150%;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.warranty {
|
||||
font-size: 10pt;
|
||||
color: #888;
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
.orange {
|
||||
fill: #fc0;
|
||||
}
|
||||
|
||||
.red {
|
||||
fill: #f00
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page">
|
||||
|
||||
<div>
|
||||
<div style="float: left; margin-right: -100%; margin-top: 0; margin-left: 3px;">
|
||||
<a href="/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="80" viewBox="0 0 9 8">
|
||||
<path class="red" d="M0,7 h1 v1 h-1 z"></path>
|
||||
<path class="orange" d="M0,0 h1 v7 h-1 z"></path>
|
||||
<path class="orange" d="M2,0 h1 v8 h-1 z"></path>
|
||||
<path class="orange" d="M4,0 h1 v8 h-1 z"></path>
|
||||
<path class="orange" d="M6,0 h1 v8 h-1 z"></path>
|
||||
<path class="orange" d="M8,3.25 h1 v1.5 h-1 z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h1 id="main_title"><a class="title_link" href="/">ClickHouse</a></h1>
|
||||
<h2>Tutorial</h2>
|
||||
</div>
|
||||
|
||||
<p>Let's get started with sample dataset from open sources. We will use USA civil flights data since 1987 till 2015.
|
||||
It's hard to call this sample a Big Data (contains 166 millions rows, 63 Gb of uncompressed data) but this
|
||||
allows us to quickly get to work. Dataset is available for download <a href="https://yadi.sk/d/pOZxpa42sDdgm">here</a>.
|
||||
Also you may download it from the original datasource <a
|
||||
href="https://github.com/yandex/ClickHouse/raw/master/doc/example_datasets/1_ontime.txt"
|
||||
rel="external nofollow">as described
|
||||
here</a>.</p>
|
||||
|
||||
<p>Firstly we will deploy ClickHouse to a single server. Below that we will also review the process of deployment to
|
||||
a cluster with support for sharding and replication.</p>
|
||||
|
||||
<p>On Ubuntu and Debian Linux ClickHouse can be installed from <a href="/#download">packages</a>.
|
||||
For other Linux distributions you can <a href="https://github.com/yandex/ClickHouse/blob/master/doc/build.md"
|
||||
rel="external nofollow">compile
|
||||
ClickHouse from sources</a> and then install.</p>
|
||||
|
||||
<p><b>clickhouse-client</b> package contains <a
|
||||
href="/reference_en.html#Command-line%20client">clickhouse-client</a> application —
|
||||
interactive ClickHouse client. <b>clickhouse-server-base</b> contains a clickhouse-server binary file. <b>clickhouse-server-common</b>
|
||||
— contains config files for the clickhouse-server.</p>
|
||||
|
||||
<p>Server config files are located in /etc/clickhouse-server/. Before getting to work please notice the <b>path</b>
|
||||
element in config. <b>Path</b> determines the location for data storage. It's not really handy to directly
|
||||
edit <b>config.xml</b> file considering package updates. Recommended way is to override the config elements in
|
||||
<a href="/reference_en.html#Configuration%20files">files of config.d directory</a>.
|
||||
Also you may want to <a href="/reference_en.html#Access%20rights">set up access
|
||||
rights</a> at the start.</p>
|
||||
|
||||
<p><b>clickhouse-server</b> won't be launched automatically after package installation. It won't be automatically
|
||||
restarted after updates either. Start the server with:
|
||||
<pre>sudo service clickhouse-server start</pre>
|
||||
Default location for server logs is /var/log/clickhouse-server/
|
||||
Server is ready to handle client conections once "Ready for connections" message was logged.</p>
|
||||
|
||||
<p>Use <b>clickhouse-client</b> to connect to the server.</p>
|
||||
|
||||
<div class="spoiler"><a class="spoiler_title">Tips for clickhouse-client</a>
|
||||
<div class="spoiler_body">
|
||||
Interactive mode:
|
||||
<pre>
|
||||
clickhouse-client
|
||||
clickhouse-client --host=... --port=... --user=... --password=...
|
||||
</pre>
|
||||
Enable multiline queries:
|
||||
<pre>
|
||||
clickhouse-client -m
|
||||
clickhouse-client --multiline
|
||||
</pre>
|
||||
Run queries in batch-mode:
|
||||
<pre>
|
||||
clickhouse-client --query='SELECT 1'
|
||||
echo 'SELECT 1' | clickhouse-client
|
||||
</pre>
|
||||
Inser data from file of a specified format:
|
||||
<pre>
|
||||
clickhouse-client --query='INSERT INTO table VALUES' < data.txt
|
||||
clickhouse-client --query='INSERT INTO table FORMAT TabSeparated' < data.tsv
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Create table for sample dataset</h3>
|
||||
<div class="spoiler"><a class="spoiler_title">Create table query</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
$ clickhouse-client --multiline
|
||||
ClickHouse client version 0.0.53720.
|
||||
Connecting to localhost:9000.
|
||||
Connected to ClickHouse server version 0.0.53720.
|
||||
|
||||
:) CREATE TABLE ontime
|
||||
(
|
||||
Year UInt16,
|
||||
Quarter UInt8,
|
||||
Month UInt8,
|
||||
DayofMonth UInt8,
|
||||
DayOfWeek UInt8,
|
||||
FlightDate Date,
|
||||
UniqueCarrier FixedString(7),
|
||||
AirlineID Int32,
|
||||
Carrier FixedString(2),
|
||||
TailNum String,
|
||||
FlightNum String,
|
||||
OriginAirportID Int32,
|
||||
OriginAirportSeqID Int32,
|
||||
OriginCityMarketID Int32,
|
||||
Origin FixedString(5),
|
||||
OriginCityName String,
|
||||
OriginState FixedString(2),
|
||||
OriginStateFips String,
|
||||
OriginStateName String,
|
||||
OriginWac Int32,
|
||||
DestAirportID Int32,
|
||||
DestAirportSeqID Int32,
|
||||
DestCityMarketID Int32,
|
||||
Dest FixedString(5),
|
||||
DestCityName String,
|
||||
DestState FixedString(2),
|
||||
DestStateFips String,
|
||||
DestStateName String,
|
||||
DestWac Int32,
|
||||
CRSDepTime Int32,
|
||||
DepTime Int32,
|
||||
DepDelay Int32,
|
||||
DepDelayMinutes Int32,
|
||||
DepDel15 Int32,
|
||||
DepartureDelayGroups String,
|
||||
DepTimeBlk String,
|
||||
TaxiOut Int32,
|
||||
WheelsOff Int32,
|
||||
WheelsOn Int32,
|
||||
TaxiIn Int32,
|
||||
CRSArrTime Int32,
|
||||
ArrTime Int32,
|
||||
ArrDelay Int32,
|
||||
ArrDelayMinutes Int32,
|
||||
ArrDel15 Int32,
|
||||
ArrivalDelayGroups Int32,
|
||||
ArrTimeBlk String,
|
||||
Cancelled UInt8,
|
||||
CancellationCode FixedString(1),
|
||||
Diverted UInt8,
|
||||
CRSElapsedTime Int32,
|
||||
ActualElapsedTime Int32,
|
||||
AirTime Int32,
|
||||
Flights Int32,
|
||||
Distance Int32,
|
||||
DistanceGroup UInt8,
|
||||
CarrierDelay Int32,
|
||||
WeatherDelay Int32,
|
||||
NASDelay Int32,
|
||||
SecurityDelay Int32,
|
||||
LateAircraftDelay Int32,
|
||||
FirstDepTime String,
|
||||
TotalAddGTime String,
|
||||
LongestAddGTime String,
|
||||
DivAirportLandings String,
|
||||
DivReachedDest String,
|
||||
DivActualElapsedTime String,
|
||||
DivArrDelay String,
|
||||
DivDistance String,
|
||||
Div1Airport String,
|
||||
Div1AirportID Int32,
|
||||
Div1AirportSeqID Int32,
|
||||
Div1WheelsOn String,
|
||||
Div1TotalGTime String,
|
||||
Div1LongestGTime String,
|
||||
Div1WheelsOff String,
|
||||
Div1TailNum String,
|
||||
Div2Airport String,
|
||||
Div2AirportID Int32,
|
||||
Div2AirportSeqID Int32,
|
||||
Div2WheelsOn String,
|
||||
Div2TotalGTime String,
|
||||
Div2LongestGTime String,
|
||||
Div2WheelsOff String,
|
||||
Div2TailNum String,
|
||||
Div3Airport String,
|
||||
Div3AirportID Int32,
|
||||
Div3AirportSeqID Int32,
|
||||
Div3WheelsOn String,
|
||||
Div3TotalGTime String,
|
||||
Div3LongestGTime String,
|
||||
Div3WheelsOff String,
|
||||
Div3TailNum String,
|
||||
Div4Airport String,
|
||||
Div4AirportID Int32,
|
||||
Div4AirportSeqID Int32,
|
||||
Div4WheelsOn String,
|
||||
Div4TotalGTime String,
|
||||
Div4LongestGTime String,
|
||||
Div4WheelsOff String,
|
||||
Div4TailNum String,
|
||||
Div5Airport String,
|
||||
Div5AirportID Int32,
|
||||
Div5AirportSeqID Int32,
|
||||
Div5WheelsOn String,
|
||||
Div5TotalGTime String,
|
||||
Div5LongestGTime String,
|
||||
Div5WheelsOff String,
|
||||
Div5TailNum String
|
||||
)
|
||||
ENGINE = MergeTree(FlightDate, (Year, FlightDate), 8192);
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Now we have a table of <a href="/reference_en.html#MergeTree">MergeTree type</a>.
|
||||
MergeTree table type is recommended for usage in production. Table of this kind has a primary key used for
|
||||
incremental sort of table data. This allows fast execution of queries in ranges of a primary key.</p>
|
||||
|
||||
|
||||
<p><b>Note</b>
|
||||
We store ad network banners impressions logs in ClickHouse. Each table entry looks like:
|
||||
<source>
|
||||
[Advertiser ID, Impression ID, attribute1, attribute2, …]</pre>
|
||||
Let assume that our aim is to provide a set of reports for each advertiser. Common and frequently demanded query
|
||||
would be to count impressions for a specific Advertiser ID. This means that table primary key should start with
|
||||
<source>
|
||||
Advertiser ID</pre>. In this case ClickHouse needs to read smaller amount of data to perform the query for a
|
||||
given
|
||||
<source>
|
||||
Advertiser ID</pre>.
|
||||
</p>
|
||||
|
||||
<h3>Load data</h3>
|
||||
<pre>xz -v -c -d < ontime.csv.xz | clickhouse-client --query="INSERT INTO ontime FORMAT CSV"</pre>
|
||||
<p>ClickHouse INSERT query allows to load data in any <a href="/reference_en.html#Formats">supported
|
||||
format</a>. Data load requires just O(1) RAM consumption. INSERT query can receive any data volume as input.
|
||||
It's strongly recommended to insert data with <a
|
||||
href="/reference_en.html#Performance%20on%20data%20insertion.">not too small
|
||||
size blocks</a>. Notice that insert of blocks with size up to max_insert_block_size (= 1 048 576
|
||||
rows by default) is an atomic operation: data block will be inserted completely or not inserted at all. In case
|
||||
of disconnect during insert operation you may not know if the block was inserted successfully. To achieve
|
||||
exactly-once semantics ClickHouse supports idempotency for <a
|
||||
href="/reference_en.html#Data%20replication">replicated tables</a>. This means
|
||||
that you may retry insert of the same data block (possibly on a different replicas) but this block will be
|
||||
inserted just once. Anyway in this guide we will load data from our localhost so we may not take care about data
|
||||
blocks generation and exactly-once semantics.</p>
|
||||
|
||||
<p>INSERT query into tables of MergeTree type is non-blocking (so does a SELECT query). You can execute SELECT
|
||||
queries right after of during insert operation.</p>
|
||||
|
||||
<p>Our sample dataset is a bit not optimal. There are two reasons.</p>
|
||||
|
||||
<p>The first is that String data type is used in cases when <a
|
||||
href="/reference_en.html#Enum">Enum</a> or numeric type would fit best.</p>
|
||||
|
||||
<p class="tip"><b>⚖</b> When set of possible values is determined and known to be small. (E.g. OS name, browser
|
||||
vendors etc.) it's recommended to use Enums or numbers to improve performance.
|
||||
When set of possible values is not limited (search query, URL, etc.) just go ahead with String.</p>
|
||||
|
||||
<p>The second is that dataset contains redundant fields like Year, Quarter, Month, DayOfMonth, DayOfWeek. In fact a
|
||||
single FlightDate would be enough. Most likely they have been added to improve performance for other DBMS'es
|
||||
which DateTime handling functions may be not efficient.</p>
|
||||
|
||||
<p class="tip"><b>✯</b> ClickHouse <a
|
||||
href="/reference_en.html#Functions%20for%20working%20with%20dates%20and%20times">functions
|
||||
for operating with DateTime fields</a> are well-optimized so such redundancy is not required. Anyway much
|
||||
columns is not a reason to worry — ClickHouse is a <a href="https://en.wikipedia.org/wiki/Column-oriented_DBMS">column-oriented
|
||||
DBMS</a>. This allows you to have as much fields as you need. Hundreds of columns in a table is fine for
|
||||
ClickHouse.</p>
|
||||
|
||||
<h3>Querying the sample dataset</h3>
|
||||
|
||||
<p>Here are some examples of the queries from our test data.</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">the most popular destinations in 2015;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT
|
||||
OriginCityName,
|
||||
DestCityName,
|
||||
count(*) AS flights,
|
||||
bar(flights, 0, 20000, 40)
|
||||
FROM ontime WHERE Year = 2015 GROUP BY OriginCityName, DestCityName ORDER BY flights DESC LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/a85/18a/200/a8518a200d6d405a95ee80ea1c8e1c90.png"/>
|
||||
<pre>
|
||||
SELECT
|
||||
OriginCityName < DestCityName ? OriginCityName : DestCityName AS a,
|
||||
OriginCityName < DestCityName ? DestCityName : OriginCityName AS b,
|
||||
count(*) AS flights,
|
||||
bar(flights, 0, 40000, 40)
|
||||
FROM ontime WHERE Year = 2015 GROUP BY a, b ORDER BY flights DESC LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/d35/78d/b55/d3578db55e304bd7b5eba818abdb53f5.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">the most popular cities of departure;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT OriginCityName, count(*) AS flights
|
||||
FROM ontime GROUP BY OriginCityName ORDER BY flights DESC LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/ef4/141/f34/ef4141f348234773a5349c4bd3e8f804.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">cities of departure which offer maximum variety of
|
||||
destinations;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT OriginCityName, uniq(Dest) AS u
|
||||
FROM ontime GROUP BY OriginCityName ORDER BY u DESC LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/240/9f4/9d1/2409f49d11fb4aa1b8b5ff34cf9ca75d.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">flight delay dependence on the day of week;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT DayOfWeek, count() AS c, avg(DepDelay > 60) AS delays
|
||||
FROM ontime GROUP BY DayOfWeek ORDER BY DayOfWeek
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/885/e50/793/885e507930e34b7c8f788d25e7ca2bcf.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">cities of departure with most frequent delays for 1 hour or
|
||||
longer;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT OriginCityName, count() AS c, avg(DepDelay > 60) AS delays
|
||||
FROM ontime
|
||||
GROUP BY OriginCityName
|
||||
HAVING c > 100000
|
||||
ORDER BY delays DESC
|
||||
LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/ac2/926/56d/ac292656d03946d0aba35c75783a31f2.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">flights of maximum duration;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT OriginCityName, DestCityName, count(*) AS flights, avg(AirTime) AS duration
|
||||
FROM ontime
|
||||
GROUP BY OriginCityName, DestCityName
|
||||
ORDER BY duration DESC
|
||||
LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/7b3/c2e/685/7b3c2e685832439b8c373bf2015131d2.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">distribution of arrival time delays split by aircompanies;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT Carrier, count() AS c, round(quantileTDigest(0.99)(DepDelay), 2) AS q
|
||||
FROM ontime GROUP BY Carrier ORDER BY q DESC
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/49c/332/e3d/49c332e3d93146ba8f46beef6b2b02b0.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">aircompanies who stopped flights operation;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT Carrier, min(Year), max(Year), count()
|
||||
FROM ontime GROUP BY Carrier HAVING max(Year) < 2015 ORDER BY count() DESC
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/249/56f/1a2/24956f1a2efc48d78212586958aa036c.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">most trending destination cities in 2015;</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT
|
||||
DestCityName,
|
||||
sum(Year = 2014) AS c2014,
|
||||
sum(Year = 2015) AS c2015,
|
||||
c2015 / c2014 AS diff
|
||||
FROM ontime
|
||||
WHERE Year IN (2014, 2015)
|
||||
GROUP BY DestCityName
|
||||
HAVING c2014 > 10000 AND c2015 > 1000 AND diff > 1
|
||||
ORDER BY diff DESC
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/f31/32f/4d1/f3132f4d1c0d42eab26d9111afe7771a.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="spoiler"><a class="spoiler_title">destination cities with maximum popularity-season
|
||||
dependency.</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
SELECT
|
||||
DestCityName,
|
||||
any(total),
|
||||
avg(abs(monthly * 12 - total) / total) AS avg_month_diff
|
||||
FROM
|
||||
(
|
||||
SELECT DestCityName, count() AS total
|
||||
FROM ontime GROUP BY DestCityName HAVING total > 100000
|
||||
)
|
||||
ALL INNER JOIN
|
||||
(
|
||||
SELECT DestCityName, Month, count() AS monthly
|
||||
FROM ontime GROUP BY DestCityName, Month HAVING monthly > 10000
|
||||
)
|
||||
USING DestCityName
|
||||
GROUP BY DestCityName
|
||||
ORDER BY avg_month_diff DESC
|
||||
LIMIT 20
|
||||
</pre>
|
||||
<img src="https://habrastorage.org/files/26b/2c7/aae/26b2c7aae21a4c76800cb1c7a33a374d.png"/></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>ClickHouse deployment to cluster</h3>
|
||||
<p>ClickHouse cluster is a homogenous cluster. Steps to set up:
|
||||
<ol>
|
||||
<li>Install ClickHouse server on all machines of the cluster</li>
|
||||
<li>Set up cluster configs in configuration file</li>
|
||||
<li>Create local tables on each instance</li>
|
||||
<li>Create a <a href="/reference_en.html#Distributed">Distributed table</a></li>
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
<p><a href="/reference_en.html#Distributed">Distributed-table</a> is actually a kind of
|
||||
"view" to local tables of ClickHouse cluster. SELECT query from a distributed table will be executed using
|
||||
resources of all cluster's shards. You may specify configs for multiple clusters and create multiple
|
||||
Distributed-tables providing views to different clusters.</p>
|
||||
|
||||
<div class="spoiler"><a class="spoiler_title">Config for cluster of three shards. Each shard stores data on a single
|
||||
replica</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
<remote_servers>
|
||||
<perftest_3shards_1replicas>
|
||||
<shard>
|
||||
<replica>
|
||||
<host>example-perftest01j.yandex.ru</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
</shard>
|
||||
<shard>
|
||||
<replica>
|
||||
<host>example-perftest02j.yandex.ru</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
</shard>
|
||||
<shard>
|
||||
<replica>
|
||||
<host>example-perftest03j.yandex.ru</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
</shard>
|
||||
</perftest_3shards_1replicas>
|
||||
</remote_servers>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
Creating a local table:
|
||||
<pre>CREATE TABLE ontime_local (...) ENGINE = MergeTree(FlightDate, (Year, FlightDate), 8192);</pre>
|
||||
Creating a distributed table providing a view into local tables of the cluster:
|
||||
<pre>CREATE TABLE ontime_all AS ontime_local
|
||||
ENGINE = Distributed(perftest_3shards_1replicas, default, ontime_local, rand());</pre>
|
||||
|
||||
<p>You can create a Distributed table on all machines in the cluster. This would allow to run distributed queries on
|
||||
any machine of the cluster. Besides distributed table you can also use <a
|
||||
href="/reference_en.html#remote">*remote* table function</a>.</p>
|
||||
|
||||
<p>Let's run <a href="/reference_en.html#INSERT">INSERT SELECT</a> into Distributed table
|
||||
to spread the table to multiple servers.</p>
|
||||
|
||||
<pre>INSERT INTO ontime_all SELECT * FROM ontime;</pre>
|
||||
|
||||
<p class="tip"><b>⚠</b> Worth to notice that the approach given above wouldn't fit for sharding of large
|
||||
tables.<br/>Please use <a href="/reference_en.html#Resharding">built-in sharding
|
||||
feature</a>.</p>
|
||||
|
||||
<p>As you could expect heavy queries are executed N times faster being launched on 3 servers instead of one.</p>
|
||||
<div class="spoiler"><a class="spoiler_title">See here</a>
|
||||
<div class="spoiler_body">
|
||||
<img src="https://habrastorage.org/files/ece/020/129/ece020129fdf4a18a6e75daf2e699cb9.png"/>
|
||||
|
||||
<p>You may have noticed that quantiles calculation are slightly different. This happens due to <a
|
||||
href="https://github.com/tdunning/t-digest/raw/master/docs/t-digest-paper/histo.pdf">t-digest</a>
|
||||
algorithm implementation which is non-deterministic — it depends on the order of data processing.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>In this case we have used a cluster with 3 shards each contains a single replica.</p>
|
||||
|
||||
<p>To provide for resilience in production environment we recommend that each shard should contain 2-3 replicas
|
||||
distributed between multiple data-centers. Note that ClickHouse supports unlimited number of replicas.</p>
|
||||
|
||||
<div class="spoiler"><a class="spoiler_title">Config for cluster of one shard containing three replicas</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
<remote_servers>
|
||||
...
|
||||
<perftest_1shards_3replicas>
|
||||
<shard>
|
||||
<replica>
|
||||
<host>example-perftest01j.yandex.ru</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
<replica>
|
||||
<host>example-perftest02j.yandex.ru</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
<replica>
|
||||
<host>example-perftest03j.yandex.ru</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
</shard>
|
||||
</perftest_1shards_3replicas>
|
||||
</remote_servers>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>To enable replication <a href="http://zookeeper.apache.org/">ZooKeeper</a> is required. ClickHouse will take care
|
||||
of data consistency on all replicas and run restore procedure after failure automatically. It's recommended to
|
||||
deploy ZooKeeper cluster to separate servers.</p>
|
||||
|
||||
<p>ZooKeeper is not a requirement — in some simple cases you can duplicate the data by writing it into all the
|
||||
replicas from your application code. This approach is not recommended — in this case ClickHouse is not able to
|
||||
guarantee data consistency on all replicas. This remains the responsibility of your application.</p>
|
||||
|
||||
<div class="spoiler"><a class="spoiler_title">Set ZooKeeper locations in configuration file</a>
|
||||
<div class="spoiler_body">
|
||||
<pre>
|
||||
<zookeeper-servers>
|
||||
<node>
|
||||
<host>zoo01.yandex.ru</host>
|
||||
<port>2181</port>
|
||||
</node>
|
||||
<node>
|
||||
<host>zoo02.yandex.ru</host>
|
||||
<port>2181</port>
|
||||
</node>
|
||||
<node>
|
||||
<host>zoo03.yandex.ru</host>
|
||||
<port>2181</port>
|
||||
</node>
|
||||
</zookeeper-servers>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Also we need to set macros for identifying shard and replica — it will be used on table creation</p>
|
||||
<pre>
|
||||
<macros>
|
||||
<shard>01</shard>
|
||||
<replica>01</replica>
|
||||
</macros>
|
||||
</pre>
|
||||
<p>If there are no replicas at the moment on replicated table creation — a new first replica will be instantiated.
|
||||
If there are already live replicas — new replica will clone the data from existing ones. You have an option to
|
||||
create all replicated tables first and that insert data to it. Another option is to create some replicas and add
|
||||
the others after or during data insertion.</p>
|
||||
|
||||
<pre>
|
||||
CREATE TABLE ontime_replica (...)
|
||||
ENGINE = ReplicatedMergeTree(
|
||||
'/clickhouse_perftest/tables/{shard}/ontime',
|
||||
'{replica}',
|
||||
FlightDate,
|
||||
(Year, FlightDate),
|
||||
8192);
|
||||
</pre>
|
||||
<p>Here we use <a href="/reference_en.html#ReplicatedMergeTree">ReplicatedMergeTree</a>
|
||||
table type. In parameters we specify ZooKeeper path containing shard and replica identifiers.</p>
|
||||
|
||||
<pre>INSERT INTO ontime_replica SELECT * FROM ontime;</pre>
|
||||
<p>Replication operates in multi-master mode. Data can be loaded into any replica — it will be synced with other
|
||||
instances automatically. Replication is asynchronous so at a given moment of time not all replicas may contain
|
||||
recently inserted data. To allow data insertion at least one replica should be up. Others will sync up data and
|
||||
repair consistency once they will become active again. Please notice that such scheme allows for the possibility
|
||||
of just appended data loss.</p>
|
||||
|
||||
<h3>Feedback</h3>
|
||||
|
||||
<p>Ask any questions on <a href="https://stackoverflow.com/questions/tagged/clickhouse" rel="external nofollow">Stack
|
||||
Overflow</a>.</p>
|
||||
<p>Discuss with real users in Telegram chat in <a href="https://telegram.me/clickhouse_en" rel="external nofollow">English</a>
|
||||
or in <a
|
||||
href="https://telegram.me/clickhouse_ru" rel="external nofollow">Russian</a>.</p>
|
||||
<p>Use <a href="https://groups.google.com/group/clickhouse" rel="external nofollow">Google Group</a> for discussion.
|
||||
</p>
|
||||
<p>Or send private message to developers:
|
||||
<a id="feedback_email" href="">turn on JavaScript to see email address</a>.
|
||||
</p>
|
||||
<p class="warranty">Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
either express or implied.</p>
|
||||
|
||||
<p class="footer">© 2016–2017 <a href="https://yandex.com/company/" rel="external nofollow">YANDEX</a> LLC</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="https://yastatic.net/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function getParams() {
|
||||
var matches = document.cookie.match(/yandex_login=([\w\-]+)/);
|
||||
return (matches && matches.length == 2) ? {"login": matches[1]} : {};
|
||||
}
|
||||
$('.spoiler_title').click(function () {
|
||||
$(this).next('.spoiler_body').toggle(100);
|
||||
});
|
||||
|
||||
var name = document.getElementById('main_title').textContent.trim().toLowerCase();
|
||||
var feedback_address = name + '-feedback' + '@yandex-team.com';
|
||||
var feedback_email = document.getElementById('feedback_email');
|
||||
feedback_email.setAttribute('href', 'mailto:' + feedback_address);
|
||||
feedback_email.textContent = feedback_address;
|
||||
</script>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script src="https://mc.yandex.ru/metrika/watch.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var yaCounter18343495 = new Ya.Metrika({
|
||||
id: 18343495,
|
||||
webvisor: true,
|
||||
clickmap: true,
|
||||
trackLinks: true,
|
||||
accurateTrackBounce: true,
|
||||
trackHash: true,
|
||||
params: getParams()
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
</script>
|
||||
<noscript>
|
||||
<div><img src="https://mc.yandex.ru/watch/18343495" style="position:absolute; left:-9999px;" alt=""/></div>
|
||||
</noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
website/yandex-black-button.png
Normal file
After Width: | Height: | Size: 724 B |
BIN
website/yandex-white-button.png
Normal file
After Width: | Height: | Size: 810 B |