-
Notifications
You must be signed in to change notification settings - Fork 37
/
index.html
186 lines (143 loc) · 6.16 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>Cassandra Parameters for Dummies</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js" type="text/javascript"></script>
<style>
body { width: 800px; margin-left:auto; margin-right:auto; font-family: Arial, sans}
input { width: 5em; }
.field { margin-right:20px; display:inline;}
.calculated { font-size: 18px; margin:20px 100px 0px 100px; width: 600px; display:block; }
.calculated span {
font-size: 22px;
color: #0000FF;
}
.help {
font-size: 9px;
}
.comments {
font-size: 10px;
margin: 30px 100px 0px 100px;
float:right;
}
</style>
</head>
<body>
<h1>Cassandra Parameters for Dummies</h1>
<p>This simple form allows you to try out different values for your <a href="http://cassandra.apache.org">Apache Cassandra</a> cluster
and see what the impact is for your application.</p>
<form id="cassForm" action="#">
<div class="field">
<label for="N">Cluster size</label>
<input type="int" name="N" id="N" value="1" size="5"></input>
</div>
<div class="field">
<label for="RF">Replication Factor</label>
<input type="int" name="RF" id="RF" value="1" size="5"></input>
</div>
<div class="field">
<label for="W">Write Level</label>
<select id="W" name="W">
<option value="one">ONE</option>
<option value="two">TWO</option>
<option value="three">THREE</option>
<option value="quorum">QUORUM</option>
<option value="all">ALL</option>
</select>
</div>
<div class="field">
<label for="R">Read Level</label>
<select id="R" name="R">
<option value="one">ONE</option>
<option value="two">TWO</option>
<option value="three">THREE</option>
<option value="quorum">QUORUM</option>
<option value="all">ALL</option>
</select>
</div>
<hr />
<div class="calculated">
Your reads are <span id="consistency"></span>
<div class="help">"Consistent" means that for this particular Read/Write level combo, all nodes will "see" the same data. "Eventually consistent" means
that you might get old data from some nodes and new data for others until the data has been replicated across all devices. The idea is that this way you can
increase read/write speeds and improve tolerance against dead nodes.</div>
</div>
<div class="calculated">
You can survive the loss of <span id="loss"></span> without impacting the application.
<div class="help">How many nodes can go down without application noticing? This is a lower bound - in large clusters, you could lose more nodes and if they happen to be handling different parts of the keyspace, then you wouldn't notice either.</div>
</div>
<div class="calculated">
You can survive the loss of <span id="dataloss"></span> without data loss.
<div class="help">How many nodes can go down without physically losing data? This is a lower bound - in large clusters, you could lose more nodes and if they happen to be handling different parts of the keyspace, then you wouldn't notice either.</div>
</div>
<div class="calculated">
You are really reading from <span id="read"></span> every time.
<div class="help">The more nodes you read from, more network traffic ensues, and the bigger the latencies involved. Cassandra read operation won't return until at least this many nodes have responded with some data value.</div>
</div>
<div class="calculated">
You are really writing to <span id="write"></span> every time.
<div class="help">The more nodes you write to, more network traffic ensues, and the bigger the latencies involved. Cassandra write operation won't return until at least this many nodes have acknowledged receiving the data.</div>
</div>
<div class="calculated">
Each node holds <span id="ratio"></span> of your data.
<div class="help">The bigger your cluster is, the more the data gets distributed across your nodes. If you are using the RandomPartitioner, or are very
good at distributing your keys when you use OrderedPartitioner, this is how much data each of your nodes has to handle. This is also how much
of your keyspace becomes inaccessible for each node that you lose beyond the safe limit, above.</div>
</div>
</form>
<div class="comments">Comments? <a href="mailto:[email protected]">[email protected]</a>. You can also <a href="https://github.com/jalkanen/cassandracalculator">fork this on Github</a>.</div>
<script type="text/javascript">
recalc();
function realSize(n,x) {
if( x === 'one' ) return 1;
if( x === 'two' ) return 2;
if( x === 'three' ) return 3;
if( x === 'quorum' ) return Math.floor(n/2+1);
if( x === 'all' ) return n;
}
function recalc() {
var n = parseInt($('#N').val());
var rf = parseInt($('#RF').val());
var r = realSize(rf,$('#R').val());
var w = realSize(rf,$('#W').val());
if( r + w > rf ) $('#consistency').text('consistent');
else $('#consistency').text('eventually consistent');
$('#read').text( r > 1 ? r+" nodes" : "1 node");
$('#write').text( w > 1 ? w+" nodes" : "1 node" );
var survivable = rf-Math.max(r,w);
$('#loss').text( survivable > 1 ? survivable+" nodes" : survivable === 1 ? "1 node" : "no nodes");
var dataloss = w - 1;
$('#dataloss').text( dataloss > 1 ? dataloss+" nodes" : dataloss === 1 ? "1 node" : "no nodes");
var ratio = rf/n;
$('#ratio').text( Math.round(ratio*100)+'%' );
}
function ensureRFSanity() {
var rf = parseInt($('#RF').val());
var n = parseInt($('#N').val());
if( rf > n ) { $('#RF').val(n); }
}
$('#RF').keyup( function() {
ensureRFSanity();
recalc();
});
$('#N').keyup(function() {
ensureRFSanity();
recalc();
});
$('#R').change(function() {
recalc();
});
$('#W').change(function() {
recalc();
});
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-151738-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body> </html>