Stored procedure wrapper for Java & PGObserver
如果无法正常显示,请先停止浏览器的去广告插件。
相关话题:
#zalando
1. Stored procedure wrapper for Java
&
PGObserver
Jan Mussler | PGConf.EU 2012
2. Outline
● Introduction
● Stored procedure wrapper
●
– Problems before the wrapper
– How it works
– How to use it
– More features including sharding
PGObserver
3. Zalando
●
●
●
●
14 countries
471 Mio € revenue
1st half of 2012
3 warehouses
Europe's largest
online fashion retailer
tech.zalando.org
3
4. Zalando platform
●
●
●
●
Modern open source
software stack
Mostly Java
PostgreSQL
database backend
> 150 developers
tech.zalando.org
4
5. PostgreSQL setup
● ~ 20+ Servers PostgreSQL master servers
● ~ 4.000 GB of data
● Started with PostgreSQL 9.0 rc1
● Now running version 9.0 to 9.2
●
– cascading replication very welcome
– maintenance improvements great ( drop concurrently )
– Index only scan, pg_stat_statement improvements
Machine setup
– 8- to 48- cores, 16GB to 128GB
– SAN, no SAN with ( 2x2x RAID 1, 4x RAID 10 ) preferred
5
6. PostgreSQL availability
● BoneCP as Java connection pool
● All databases use streaming replication
–
●
Failover is manual task
–
●
Service IP for switching
Monitored by Jave app, Web frontend
Significant replication delays sometimes
–
Fullpage writes, Nested Transactions, Slave load
6
7. Stored procedure experience
● Performance benefits
● Easy to change live behavior
● Makes moving to new software version easy
● Validation close to data
● Run a very simplistic transaction scope
● Cross language API layer
● More than 1000 stored procedures
–
More plpgsql than SQL than plpython
7
8. Outline
● Introduction
● Stored procedure wrapper
●
– Problems before the wrapper
– How it works
– How to use it
– More features including sharding
PGObserver
9. Execution of stored procedures
●
●
Using spring's BaseStoredProcudere
– Initially a lot of work per stored procedure
– One class per stored procedure
– Write row mappers for domain object mapping
Missing type mapper on Java side
–
Spring type mapper insufficient
●
●
Enums, array of types, nesting, and hstore missing
JdbcTemplate or alternatives lack ease of use
9
10. Goals of our wrapper
● Write as little code as possible on Java side
● One location for procedures of same topic
● One call path to any stored procedure
● “Natural” feeling for using stored procedures
– Procedure call should look like Java method call
– RPC like
10
11. Brief example
11
12. Brief example
12
13. Brief example
13
14. Outline
● Introduction
● Stored procedure wrapper
●
– Problems before the wrapper
– How it works
– How to use it
– More features including sharding
PGObserver
15. Under the hood
Service Object
Invoke method()
Proxy Object
StoredProcudure lookup
StoredProcedure Object
Datasource
Provider
Typemapper
Datasource
JDBC Connection
15
16. Features
●
●
New spring compatible type mapper
– From simple types to nested domain objects
– Supports PG enum to Java enum
Accessing sharded data supported
– Result “aggregation” across shards
– Parallel query issuing
● Advisory locking via annotation
● Set custom timeout per stored procedure
16
17. Type mapper
●
Annotations for class and member variables
–
@DatabaseType and @DatabaseField
● CamelCase to camel_case conversion
● JPA 2.0 @Column annotation supported
● Addition type conversions include:
– Nested PostgreSQL types to Java objects
– hstore to Map<String,String>
– PostgreSQL enum to Java enum ( by name )
– PostgreSQL array[] to List<?>()
18
18. Outline
● Introduction
● Stored procedure wrapper
●
– Problems before the wrapper
– How it works
– How to use it
– More features including sharding
PGObserver
19. Using the wrapper
● Considere Java to PostgreSQL plpgsql
● First define the Java interface
21
20. Using the wrapper
●
Create class implementing previous interface
22
21. Using the wrapper
●
Define DTO classes if necessary
– Input parameters
– ResultSet mapping
23
22. Using the wrapper
●
Next create analogous PostgreSQL types
CREATE TYPE t_customer AS ( id int,
name text,
address t_address[] );
●
Or use “OUT” columns
CREATE FUNCTION load_customer( INOUT id int,
OUT name text,
OUT address t_address[] )
RETURNS SETOF record AS
●
Implement stored procedures
24
23. Putting it together
●
Integration test
25
24. Outline
● Introduction
● Stored procedure wrapper
●
– Problems before the wrapper
– How it works
– How to use it
– More features including sharding
PGObserver
25. Running SQL queries
●
@SProcCall(sql=”[...]”) may run any query
– Benefit from type mapper
– Relatively easy to use
– Although mixing SQL into Java source
@SProcCall(sql=”UPDATE t SET name = ?”
+ “ WHERE id = ? ”
+ “ RETURNING id”)
int updateName(@SProcParam String newName,
@SProcParam int userId);
// allows you then to do:
int r = service.updateName('Jan',1001);
27
26. Sharding support
● Parameter annotation @ShardKey
● @ShardKey and @SProcParam may overlap
@SProcCall
Customer getCustomer(@ShardKey int shardId,
@SProcParam String cnumber)
@SProcCall
Article getArticle(@ShardKey @SProcParam ean)
● ShardedObject interface for custom classes
● Added datasource providers for translation
28
27. Different datasource providers
Article
ShardedObject
EAN
Key
EAN123
MD5
ShardKey
Strategy
[...]10
Bitmap
DataSource
Provider
01
Java code and annotations
11
*0
DataSource
DataSource
DataSource
Spring context config
29
28. Search and “Merge” result set
search()
Shard 1
ResultSet
Thread 1
Wrapper
Shard 2
●
ResultSet
Thread 2
Use searchShards where you do not know
the shard
–
●
search()
List<Result>
will run on all shards return on first find
Use runOnAllShards execute on all shards
–
Search name like 'Na%' and return one collection
30
29. Auto partitioning
Shard
Strategy
Set 1
(13 char) Shard 1
Set 2
(13 char) Shard 2
Set of EANs
(13 char)
●
●
Java method called with one large collection
– Wrapper will split collection according to key
– Execute SQL for split collection on each shard
Default behavior if @ShardKey is a collection
31
30. Java bean validation
● Annotation based validation ( JSR 303 )
● Relying on hibernate validator
● Automatically checked inside wrapper
– Less boiler plate code
– @SProcService(validate = true)
32
31. Value transformers
●
●
Global registry for type conversions
– e.g. for use with JodaTime class
– Enables transparent handling of legacy types
Usefull for ::text to Java class conversion
– Type safe domain classes
– ::text => class EAN
33
32. Per stored procedure timeout
●
Trouble with global statement timeout
–
●
Long running queries and supposedly fast ones
Added @SProcCall(timeout=x)
– X is timeout in ms
– Allows overwrite for long running jobs
– Ensures limited run time for “fast” functions
●
Search functions with too few constraints
34
33. Concurrency with advisory locks
●
Single database serves many Java instances
–
●
Synchronization may be required
Wrapper features one enum for different locks
– @SProcCall(advisoryLockType=LOCK1)
– Easy locking
– One enum warns developers of existing locks
35
34. Transaction support
●
●
●
Spring's @Transactional should work
– More or less datasource dependent
– Sharded environment more complicated
For multi shard operations wrapper provides
– Context is one procedure equals one transaction
– Immediate commit on each shard
– Commit only if all executions were successful
– Use two phase commit
Enabled on SProcService or SProcCall level
36
35. Outline
● Introduction
● Stored procedure wrapper
●
– Problems before the wrapper
– How it works
– How to use it
– More features including sharding
PGObserver
36. PGObserver
●
●
Build to monitor PostgreSQL performance
– Stored procedures as execution unit
– Track table statistics to assist identifying causes
Infrastructure
– One Java data gatherer
– Web frontend in using Python
– Metric data is stored in PostgreSQL
– Per service configuration of all gather intervals
38
37. PGObserver database view
39
38. PGObserver database view
CPU vs Sproc Load
IO related stats
Top 10 by runtime
Top 10 by calls
40
39. Sequential scan in live env.
Total runtime per monitored 15min
Avg. run time per call
Avg. self time per call
41
40. Table I/O data excerpt
Table size
Index size
Sequential scans
42
41. Summary
● Stored procedures can improve performance
● Type mapper great library to reduce map code
● Wrapper makes procedure usage a lot easier
●
●
Stored procedure and general PostgreSQL
performance monitoring is very important
Wrapper and PGObserver available soon!
Visit us on:
http://www.github.com/zalando
http://tech.zalando.org
43
42. Thank you for listening
Jan Mussler | PGConf.EU 2012 44