Designing Scalable Architectures with MySQL Proxy

Post on 11-Apr-2015

390 views 0 download

transcript

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 1

Designing ScalableArchitectures

with MySQL Proxy

Giuseppe MaxiaMySQL Community Team Leader - Sun Microsystems

John LoehrerData Architect, Gaia Online

Jimmy GuerreroSr Product Marketing Manager - Sun Microsystems, Database Group

Agenda• Proxy concepts• MySQL Proxy architecture• Proxy with a single back-end• Proxy with multiple back-ends

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

• broken?•missing feature?• not flexible?

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

traditional waySolving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

1. file a bug report

traditional waySolving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

1. file a bug report2. wait

traditional waySolving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

1. file a bug report2. wait

traditional waySolving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

source code

modify

new source code

compile

• Open source waySolving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

bring the logic at application

level

• creative (shortsighted) way

Solving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

set the logic at server level

(stored routines)

• creative (enlightened) way

Solving database problems

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

set the logic at protocol level

(proxy)

• creative (more enlightened) way

Solving database problems

what can you do with MySQL Proxy• create new commands• filter queries (deny specific queries)• collect statistics on usage• implement usage quotas• execute shell commands• create customized logs• implement server-side pivot tables• start/stop a MySQL server remotely• play movies (seriously!)• make coffee (really?)• sharding• load balancing servers

Basic principles

Basic principles

PROXY CORE

connection hook

read query hook

read result hook

function

Lua script

function

functionfunctionfunction

Lua

??Why not ...{Perl ?

PHP?Javascript?[whatever]?

Lua

• SMALL ( < 200 KB)• DESIGNED for

EMBEDDED systems• Widely used (lighttpd)

lighttpd, like MySQL Proxy, was created by Jan Kneschke

Lua

Very popular among game writers

Proxy overview

connect_server

Lua script

read_auth

read_auth_result

read_handshake

read_query

read_query_result

disconnect_client

global context

session contextsession

contextsession contextsession

contextsession contextsession

contextsession context

Proxy overview/usr/local/sbin/mysql-proxy \ --proxy-lua-script=/path/name.lua

IMPORTANT!THE SCRIPT DOES NOT START UNTIL THE FIRST

CLIENT CONNECTION

read_query and read_query_resultclient

MySQL Proxy

SERVER

query

functionread_query

function

read_query_result

query

result

result

if a query is passed directly to the server, its result is NOT evaluated by read_query_result

read_query and read_query_resultclient

MySQL Proxy

SERVER

query

function read_query

function

read_query_result

query queue

query

result

result

only if a query is added to the query queue, its result is evaluated by read_query_result

queryquery

An example: user quotas• You want to limit user access • When the user reaches a given amount of data,

further queries should be rejected• the quota must work across sessions

(code online)http://forge.mysql.com/tools/tool.php?id=111

User quotas-- some global variables

-- proxy.global.bandwidth-- will sum up the used bytes

proxy.global.bandwidth = proxy.global.bandwidth or {}

-- session_user will identify the user-- throughout the sessionlocal session_user

User quotas-- session_user needs to be initialized-- when the user information is passed-- (during the authentication)

function read_auth( auth ) session_user = auth.username proxy.global.bandwidth[session_user] = proxy.global.bandwidth[session_user] or 0end

BREAK (a handy Lua idiom)-- simple assignment

-- corresponds to:

if a ~= nilthen a = aelse a = 0 end

if a == nilthen a = 0else a = a end

a = a or 0

BREAK (a handy Proxy Lua function )-- returns an error to the client

function error_result (msg) proxy.response = { type = proxy.MYSQLD_PACKET_ERR, errmsg = msg, errcode = 7777, sqlstate = 'X7777', } return proxy.PROXY_SEND_RESULTend

User quotas-- read_query (1)-- checking if the quota has been-- exceededfunction read_query (packet ) if proxy.global.bandwidth[session_user] > 10000 and session_user ~= 'root' then return error_result( 'you have exceeded your query quota') end-- ...

User quotas-- read_query (2)-- adding to the totalizer

-- ... proxy.global.bandwidth[session_user ] = proxy.global.bandwidth[session_user] + packet:len() proxy.queries:append(1, packet ) return proxy.PROXY_SEND_QUERYend

User quotas-- read_query_result (1)-- adding row headers to the totalizer

function read_query_result(inj) local fields = inj.resultset.fields local rows = inj.resultset.rows if fields then for i = 1, #fields do proxy.global.bandwidth[session_user] = proxy.global.bandwidth[session_user] + (fields[i] and fields[i].name:len() or 0) end

User quotas-- read_query_result (2)-- adding rows contents to the totalizer

if rows then for row in rows do for i = 1, #fields do proxy.global.bandwidth[session_user] = proxy.global.bandwidth[session_user] + (row[i] and row[i]:len() or 0) end end end end

User quotas-- read_query_result (3)-- displaying the current bandwidth

print (session_user .. ' -> ' .. proxy.global.bandwidth[session_user])end

User quotas - what the user seesmysql> select repeat('a', 10000);ERROR 7777 (X7777): you have exceeded your query quota

User quotas (VERY advanced)-- you can create another module-- to be loaded at run time-- (this is really advanced)-- and in such module you define-- a SHOW QUOTAS command

User quotas (VERY advanced)-- load_multi

User quotas (VERY advanced)mysql> pload show_quotas.lua;+--------------------------------+| info |+--------------------------------+| module "show_quota.lua" loaded | +--------------------------------+mysql> show quotas;+----------+-------+| name | quota |+----------+-------+| simple | 3578 | | root | 2111 | | msandbox | 102 | +----------+-------+

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 36

Designing ScalableArchitectures

with MySQL Proxy

Giuseppe MaxiaMySQL Community Team Leader - Sun Microsystems

John LoehrerData Architect, Gaia Online

Jimmy GuerreroSr Product Marketing Manager - Sun Microsystems, Database Group

quick-start guide to mysql muxing

ME

online hangout

for teens

5 million unique users per month

1.3 billion forum entries

How does Gaia use the proxy?

connection multiplexer

turning 7,500 connections ...

into 100 MySQL connections

MySQL Proxy

PHPMySQLServer

100 connections7,500 connections

Why MUX?

a little history ...

Gaia’s data center in 2003

our server farm...

as our site grew ...

some scaling issues

added more servers ...

site explodes

diagnose the problem

GAIA, under the hood

typical LAMP stack

Linux

Share-Nothing Architecture

each apache server = 50 connections

Parent Process

httpd

child httpd

child httpd

...

worker thread

worker thread

listener thread

...

50 connections * 150 servers = stampede

close connections each time

setup / tear-down is expensive

connecting to MySQL

connect readchallenge

writeauth

readauth OK

connect readchallenge

writeauth

readauth OK write query read result

connect readchallenge

writeauth

readauth OK write query read result close

75% 19% 6%

MySQL Thread spawning

Client

Client MySQL Server

connect

Client MySQL Server

connect

Client MySQL Server

Threadconnect

new

Client MySQL Server

Threadconnect

accept

new

threads stack up

MySQL I/O

listen

accept

listen

accept

close

end program

NEW THREAD

listen

accept

blocking read

close

end program

NEW THREAD

listen

accept

blocking read

close

end program

NEW THREAD

blocking write

data

listen

accept

blocking read

close

close

end program

NEW THREAD

close thread

blocking write

eof data

talking to multiple databases ...

Forum DBUser DBSession DBForum Page

start session

get userdata

get topic

get related users

save session

idle threads

we need a connection pool

ideally ...

Event Queue Thread Pool

Threadallocate thread

process query

free

release the thread after each query

it’s like a limo ...

... vs. a taxi

decouple threads from connections

Libevent’s callback I/O very sweet!

listen

register callback

event dispatch

active descriptor Trigger callback

epoll/kqueue rulez! (proxy uses it)

MySQL 6.0 taking the right steps ...

In the meantime ...

by default, mysql-proxy isn’t a pooler

lua hooks are awesome!

hack some lua scripts ...

goal: recycle back-end connections

keep clients connected

proxy stays transparent

how to twist the proxy into a pooler

connecting: find an idle back-end

client

Proxy

client

Proxy

idle poolconnect ahead

authentication

Client Proxy Back-End Pool

MySQL Server

Client Proxy Back-End Pool

MySQL Server

Client Proxy Back-End Pool

MySQL Serverconnect

Client Proxy Back-End Pool

MySQL Serverconnectallocate

Client Proxy Back-End Pool

MySQL Serverconnectallocate

Client Proxy Back-End Pool

MySQL Serverconnectallocate

com-change-user

Client Proxy Back-End Pool

MySQL Serverconnectallocate

com-change-user

challenge

Client Proxy Back-End Pool

MySQL Serverconnectallocate

com-change-user

challenge

authenticate

Client Proxy Back-End Pool

MySQL Serverconnectallocate

com-change-user

challenge

authenticate

OK

Client Proxy Back-End Pool

MySQL Serverconnectallocate

com-change-user

free back-end

challenge

authenticate

OK

run the query

don’t be afraid to let go

Client Proxy

query

Client Proxy Back-End Pool

queryallocate

Client Proxy Back-End Pool

MySQL Serverqueryallocate

process query

Client Proxy Back-End Pool

MySQL Serverqueryallocate

process query

free back-end

connections scale!

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 160

Giuseppe MaxiaMySQL Community Team Leader - Sun Microsystems

John LoehrerData Architect, Gaiaonline

Jimmy GuerreroSr Product Marketing Manager - Sun Microsystems, Database Group

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.

Designing ScalableArchitectures

with MySQL Proxy

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 161

MySQL software which can route database queries to the appropriate database in a scale-out environment.

• Improves/scales throughput of reads for online applications• Helps customers reduce cost of adding slaves

• Intelligently route reads across slaves• Use database least behind, least loaded• Remove latent slaves from read rotation• Other distribution algorithms

MySQL Load Balancer

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 162

MySQL Enterprise Monitor feature that allows users to trace, monitor, and analyze MySQL query activity for specific servers, users, and applications.

• Adaptive “Evil” query collection/tracing• Historical browsing/analysis

• “Needle in a haystack” identification of worst queries

• Worst execution times, # of execs, etc.

SQL code is the #2 cause of performance issues 97% of those surveyed will use this

MySQL Query Analyzer

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 163

MySQL Query Analyzer

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 164

Next StepsMySQL Proxy Forumhttp://forums.mysql.com/list.php?146

Documentation – MySQL Proxy

http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy.html

Documentation – MySQL Load Balancer

http://dev.mysql.com/doc/refman/5.1/en/load-balancer.html

Beta Testing MySQL Proxy-Enabled Products

enterprise-beta@mysql.com

MySQL Proxy Online Poll

http://dev.mysql.com/tech-resources/quickpolls/

Copyright 2008 MySQL AB The World’s Most Popular Open Source Database 165

Questions?

Giuseppe MaxiaMySQL Community Team Leader - Sun Microsystems

John LoehrerData Architect, Gaiaonline

Jimmy GuerreroSr Product Marketing Manager - Sun Microsystems, Database Group

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.