0
Multiverse: STM <ul>Peter Veentjer Founder of Multiverse  Software Transactional Memory http://multiverse.googlecode.com <...
Who am I <ul><li>Java Developer currently working for Qiy.
8 Years Professional Experience
Projects I worked on (and I'm proud of) </li><ul><ul><li>Expert systems / Prolog compiler/interpreters
Batch processing systems
Enterprisy backend systems </li></ul></ul><li>Main intererrests </li><ul><ul><li>Concurrency control (Java, Database, STM)
Distributed computing
Software architecture
Patterns </li></ul></ul></ul>
<ul><li>Don't wait with your questions! </li><ul><li>We still know the context
There is enough time
I like the discussion </li></ul></ul>
Agenda <ul><li>What is wrong with classic concurrency control?
Software Transactional Memory (Multiverse) as alternative concurrency control implementation </li></ul>
What is wrong? <ul><li>Operations not composable </li></ul>
public class Account{ private int balance; public synchronized int getBalance(){ Return balance; } public synchronized voi...
What is wrong? <ul><li>Operations not composable
Expose Implementation details </li></ul>
public class Account{ private int balance; public synchronized int getBalance(){ Return balance; } public synchronized inc...
public class Account{ private int balance; private Lock lock = new ReentrantLock(); public int getBalance(){ ... } public ...
What is wrong? <ul><li>Operations not composable
Expose Implementation details
Deadlock prone </li></ul>
static void transfer(Account from, Account to, int amount){ synchronized(from){ synchronized(to){ from.inc(-amount); to.in...
What is wrong? <ul><li>Operations not composable
Expose Implementation details
Deadlock prone
Operation is not atomic </li></ul>
public class Account{ private int balance; public int getBalance(){ Return balance; } public inc(int delta){ if(balance + ...
Questions? <ul><li>It this the right way to deal with the increasing number of cores?
Could concurrency control be just as easy as gc?  </li></ul>
STM: What? <ul><li>Concurrency control through database like transactions on (Java) Memory </li><ul><li>(failure) Atomicity
Consistency (task of the Java Objects)
Isolation
Durability (not provided) </li></ul></ul>
Multiverse: What? <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>...
Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
Instrumentation (very time consuming!!) </li></ul></ul></ul>
@AtomicObject public class Account{ private int balance; public int getBalance(){ Return balance; } public void inc(int de...
@AtomicObject public class Account{ private int balance; @Exclude private int ignore; public int getBalance(){ Return bala...
Multiverse: What? <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>...
Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
Instrumentation (very time consuming!!) </li></ul><li>Managed reference based </li><ul><li>Field granularity </li></ul></u...
@AtomicObject public class Account{ final Ref<Integer> balance = new Ref<Integer>(); public int getBalance(){ Return balan...
Multiverse: What? <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>...
Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
Instrumentation (very time consuming!!) </li></ul><li>Managed reference based </li><ul><li>Field granularity </li></ul></u...
Multiverse: How? <ul><li>Seperate State from Object identity </li><ul><li>Atomic Object (Object identity)
Tranlocal (State) </li></ul></ul>
@AtomicObject public class Account{ private int balance; public int getBalance(){ Return balance; } public inc(int delta){...
@AtomicObject public class Account implements AtomicObject{ AtomicReference<Account__Tranlocal> current =  New AtomicRefer...
Upcoming SlideShare
Loading in...5
×

Software Transactioneel Geheugen

455

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
455
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Software Transactioneel Geheugen"

  1. 1. Multiverse: STM <ul>Peter Veentjer Founder of Multiverse Software Transactional Memory http://multiverse.googlecode.com </ul>
  2. 2. Who am I <ul><li>Java Developer currently working for Qiy.
  3. 3. 8 Years Professional Experience
  4. 4. Projects I worked on (and I'm proud of) </li><ul><ul><li>Expert systems / Prolog compiler/interpreters
  5. 5. Batch processing systems
  6. 6. Enterprisy backend systems </li></ul></ul><li>Main intererrests </li><ul><ul><li>Concurrency control (Java, Database, STM)
  7. 7. Distributed computing
  8. 8. Software architecture
  9. 9. Patterns </li></ul></ul></ul>
  10. 10. <ul><li>Don't wait with your questions! </li><ul><li>We still know the context
  11. 11. There is enough time
  12. 12. I like the discussion </li></ul></ul>
  13. 13. Agenda <ul><li>What is wrong with classic concurrency control?
  14. 14. Software Transactional Memory (Multiverse) as alternative concurrency control implementation </li></ul>
  15. 15. What is wrong? <ul><li>Operations not composable </li></ul>
  16. 16. public class Account{ private int balance; public synchronized int getBalance(){ Return balance; } public synchronized void setBalance(int newBalance){ this.balance = newBalance; } public inc(int delta){ setBalance(getBalance()+delta); } } Not Composable
  17. 17. What is wrong? <ul><li>Operations not composable
  18. 18. Expose Implementation details </li></ul>
  19. 19. public class Account{ private int balance; public synchronized int getBalance(){ Return balance; } public synchronized inc(int delta){ this.balance += balance; } } static void transfer(Account from, Account to, int amount){ synchronized(from){ synchronized(to){ from.inc(-amount); to.inc(amount); } } } Expose implementation details
  20. 20. public class Account{ private int balance; private Lock lock = new ReentrantLock(); public int getBalance(){ ... } public inc(int delta){ lock.acquire() try{ balance+=delta; }finally{ lock.release() } } } void transfer(Account from, Account to, int amount{ synchronized(from){ synchronized(to){ from.inc(-amount); to.inc(amount); } } } Expose implementation details
  21. 21. What is wrong? <ul><li>Operations not composable
  22. 22. Expose Implementation details
  23. 23. Deadlock prone </li></ul>
  24. 24. static void transfer(Account from, Account to, int amount){ synchronized(from){ synchronized(to){ from.inc(-amount); to.inc(amount); } } } Deadlocks
  25. 25. What is wrong? <ul><li>Operations not composable
  26. 26. Expose Implementation details
  27. 27. Deadlock prone
  28. 28. Operation is not atomic </li></ul>
  29. 29. public class Account{ private int balance; public int getBalance(){ Return balance; } public inc(int delta){ if(balance + delta<0) Throw new NotEnoughCashException() this.balance += balance; } } static void transfer(Account from, Account to, int amount){ to.inc(amount); from.inc(-amount); } Not atomic
  30. 30. Questions? <ul><li>It this the right way to deal with the increasing number of cores?
  31. 31. Could concurrency control be just as easy as gc? </li></ul>
  32. 32. STM: What? <ul><li>Concurrency control through database like transactions on (Java) Memory </li><ul><li>(failure) Atomicity
  33. 33. Consistency (task of the Java Objects)
  34. 34. Isolation
  35. 35. Durability (not provided) </li></ul></ul>
  36. 36. Multiverse: What? <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>Working on it for more than 1 year
  37. 37. Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
  38. 38. Instrumentation (very time consuming!!) </li></ul></ul></ul>
  39. 39. @AtomicObject public class Account{ private int balance; public int getBalance(){ Return balance; } public void inc(int delta){ this.balance += balance; } } @AtomicMethod static void transfer(Account from, Account to, int amount){ from.inc(-amount); to.inc(amount); } Using STM: POJO based
  40. 40. @AtomicObject public class Account{ private int balance; @Exclude private int ignore; public int getBalance(){ Return balance; } public void inc(int delta){ this.balance += balance; } } Excluding fields
  41. 41. Multiverse: What? <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>Working on it for more than 1 year
  42. 42. Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
  43. 43. Instrumentation (very time consuming!!) </li></ul><li>Managed reference based </li><ul><li>Field granularity </li></ul></ul></ul>
  44. 44. @AtomicObject public class Account{ final Ref<Integer> balance = new Ref<Integer>(); public int getBalance(){ Return balance.get(); } public void inc(int delta){ balance.set(balance.get()+delta); } } @AtomicMethod static void transfer(Account from, Account to, int amount){ from.inc(-amount); to.inc(amount); } Using STM : Managed Ref based
  45. 45. Multiverse: What? <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>Working on it for more than 1 year
  46. 46. Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
  47. 47. Instrumentation (very time consuming!!) </li></ul><li>Managed reference based </li><ul><li>Field granularity </li></ul></ul><li>Akka Project of Jonas Boner </li></ul>
  48. 48. Multiverse: How? <ul><li>Seperate State from Object identity </li><ul><li>Atomic Object (Object identity)
  49. 49. Tranlocal (State) </li></ul></ul>
  50. 50. @AtomicObject public class Account{ private int balance; public int getBalance(){ Return balance; } public inc(int delta){ this.balance += balance; } } Multiverse: How
  51. 51. @AtomicObject public class Account implements AtomicObject{ AtomicReference<Account__Tranlocal> current = New AtomicReference(); public int getBalance(){ Account__Tranlocal a = getTransaction().load(this); return a.balance; } public void inc(int delta){ Account__Tranlocal a = getTransaction().load(this); a.balance+=delta; } public Account__Tranlocal load(long version){..} public boolean lock(Transaction t){..} public void store(Account__Tranlocal tranlocal){...} ... } public class Account__Tranlocal{ long version; Account atomicObject; int balance; } Multiverse: How
  52. 52. Multiverse: Failure Atomicity <ul><li>Since all changes are made on the tranlocals, just drop the transaction </li></ul>
  53. 53. Drop in collections <ul><li>Drop in collections </li><ul><li>BlockingQueue & Queue
  54. 54. BlockingDeque & Deque
  55. 55. LinkedList
  56. 56. Planned </li><ul><li>TreeMap/TreeSet
  57. 57. HashMap/HashSet
  58. 58. ArrayList </li></ul></ul></ul>
  59. 59. import java.util.*; final List<String> l = Collections.synchronizedList(new LinkedList()); void add(String item){ l.add(item); } void addAll(String... items){ for(String item:items){ l.add(item); } } Drop in collections - before
  60. 60. import java.util.*; import org.multiverse.datastructures.collections.*; final List<String> l = new StrictLinkedBlockingDeque(); void l(String item){ l.add(item); } @AtomicMethod void addAll(String... items){ for(String item:items){ l.add(item); } } Drop in collections - after
  61. 61. import java.util.*; import org.multiverse.datastructures.collections.*; final List<String> l1 = new StrictLinkedBlockingDeque(); final List<String> l2 = new StrictLinkedBlockingDeque(); @AtomicMethod void add(String item){ l1.add(item); l2.add(item); } @AtomicMethod void addAll(String... items){ for(String s: items){ add(s); } } Drop in collections – Woohaa
  62. 62. Readonly vs Update Transactions <ul><li>Update Transaction </li><ul><li>Tracks Reads (called readset)
  63. 63. Tracks Writes (called writeset)
  64. 64. Expensive to use
  65. 65. Expensive to commit </li></ul><li>Readonly Transaction </li><ul><li>Doesn't track reads/writes
  66. 66. Very cheap to use
  67. 67. No commit needed </li></ul></ul>
  68. 68. @AtomicObject public class IntRef{ private int value; public void set(int newValue){ this.newValue = newValue; } @AtomicMethod(readonly = true) public int get(){ return value; } } Readonly vs Update Transactions
  69. 69. Transactions can fail <ul><li>Transaction can fail </li><ul><li>Load conflicts </li><ul><li>Version doesn't exist anymore
  70. 70. Load ambiguity
  71. 71. ... </li></ul><li>Commit conflicts </li><ul><li>Write conflicts
  72. 72. Locks can't be obtained
  73. 73. ... </li></ul></ul><li>Transactions are retried automatically! </li></ul>
  74. 74. @AtomicObject Class IntRef{ int value = 0; @AtomicMethod(retryCount = 100) void inc(){ value++; } } Automatic retrying transactions
  75. 75. @AtomicObject Class IntRef{ int value = 0; void inc(){ Transaction t = getTransaction() if(t!=null){ //there already is a transaction value++; }else{ //there is no transaction, lets create one t = stm.startTransaction() int attempt = 1; while(attempt-1 <= 100){ try{ value++; t.commit() }catch(RecoverableException ex){ attempt++; t.abortAndReset(); } } throw new TooManyRetriesException(); } } } Automatic retrying transactions
  76. 76. Automatic retrying transactions <ul><li>Some ramblings </li><ul><li>Be careful with non transactional resources </li><ul><li>IO
  77. 77. Non transactional objects </li></ul><li>Backoff policies </li><ul><li>No backoff policy
  78. 78. Exponential backoff policy
  79. 79. Priority based backoff policy </li></ul></ul></ul>
  80. 80. STM: Notification <ul><li>retry </li></ul>
  81. 81. @AtomicObject public class TStack<E>{ private Node<E> head; public void push(E item){ head = new Node<E>(head, item); } public E pop(){ if(head == null){ retry(); } Node<E> oldHead = head; head = head.next; return oldHead.value; } static class Node{ final Node<E> next; final E value; Node(Node<E> next, E value){ this.next = next; this.value = value; } } }
  82. 82. STM: Notification <ul><li>retry </li><ul><li>multiple sources </li></ul></ul>
  83. 83. TStack<Integer> stack1 = new TStack<Integer>(); TStack<Integer> stack2 = new TStack<Integer>(); @AtomicMethod public int popFromOneOfTheStacks(){ if(!stack1.isEmpty()){ Return stack1.pop(); } if(!stack2.isEmpty()){ Return stack2.pop(); } retry(); return -1;//is never executed }
  84. 84. STM: Notification <ul><li>retry </li><ul><li>multiple sources </li></ul><li>orelse </li></ul>
  85. 85. TStack<Integer> stack1 = new TStack<Integer>(); TStack<Integer> stack2 = new TStack<Integer>(); @AtomicMethod public int popFromOneOfTheStacks(){ return new OrElseTemplate<Integer>(){ void runOr(){ return stack1.pop(); } void runElse(){ return stack2.pop(); } }.execute(); }
  86. 86. TStack<Integer> stack1 = new TStack<Integer>(); TStack<Integer> stack2 = new TStack<Integer>(); @AtomicMethod public int popFromOneOfTheStacks(){ return new OrElseTemplate<Integer>(){ void runOr(){ return stack1.pop(); } void runElse(){ return stack2.pop(); } }.execute(); }
  87. 87. atomic{ either{ stack1.pop() }orelse{ stack2.pop() } }
  88. 88. STM: Notification <ul><li>retry </li><ul><li>multiple sources </li></ul><li>orelse
  89. 89. planned </li><ul><li>bounded waits </li><ul><li>Method scope
  90. 90. Transaction scope </li></ul><li>Interruptable waits </li></ul></ul>
  91. 91. STM: Isolation <ul><li>State (Tranlocal) is not shared during execution </li><ul><li>So no dirty reads possible </li></ul><li>Transaction level read consistency based on version </li><ul><li>Repeatable reads
  92. 92. No phantom reads </li></ul><li>Oracle 'serialized' isolation level out of the box </li><ul><li>Real serialized isolation planned </li></ul></ul>
  93. 93. STM : Synchronization <ul><li>Encounter time locking
  94. 94. Commit time locking </li><ul><li>Optimistic (based on the version)
  95. 95. Higher concurrency </li><ul><li>Readers don't block writers
  96. 96. Writers don't block readers </li></ul><li>Increased chance of transaction failure </li><ul><li>Planned </li><ul><li>Optional pessimistic locking (select .. for update) </li></ul></ul></ul></ul>
  97. 97. Java Memory Model <ul><li>STM Framework for the JVM </li><ul><li>Main engine is Alpha STM Engine: TL2 Based </li></ul><li>Working on it for more than 1 year
  98. 98. Multiple Programming Models </li><ul><li>POJO based icw Annotations </li><ul><li>Object granularity
  99. 99. Instrumentation (very time consuming!!) </li></ul></ul></ul>
  100. 100. Scalability <ul><li>There is no shared state </li><ul><li>so it should scale linear </li></ul><li>Except!! the global clock (e.g. atomicLong) </li><ul><li>Strict Clock
  101. 101. Relaxed Clock </li></ul><li>Solutions </li><ul><li>Use multiple STM instances </li><ul><li>Objects can't be shared between STM instances! </li></ul><li>Remove the global clock </li><ul><li>Distributed version </li></ul></ul></ul>
  102. 102. Multiverse: Plans 1 <ul><li>Performance optimizations
  103. 103. More collection classes
  104. 104. Scala Integration
  105. 105. Profiler (sampling & event)
  106. 106. (Persistent?) version history
  107. 107. Improve Instrumentation
  108. 108. Fairness/Starvation
  109. 109. Remove the global clock
  110. 110. Distributed
  111. 111. Striping </li></ul>
  112. 112. Multiverse: Plans 2 <ul><li>JMS implementation
  113. 113. JTA implementation
  114. 114. JPA implementation </li></ul>
  115. 115. Q & A <ul>[email_address] </ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×