Architecture in Motion How Adyen achieved 100x Bert Wolters - EVP Technology bert@adyen.com
Traditional vs Today Customers are in full control
$1B 80% On Singles’ Day in China, $1Billion was On Black Friday in the U.S., nearly 80% of retailers’ processed in 1 minute and 25 seconds online traffic took place on mobile.
Companies face a lack of functionality, flexibility and innovation Stuck with legacy technology that lead to poor user experience.
One modern platform Merchant Gateway Risk management Processing Schemes Issuers Traditional value chain PSP Acquirer
This is Adyen ALL TECHNOLOGY DEVELOPED IN-HOUSE One platform, one contract, all sales channels 250+ payment methods 1200+ global employees 23 Global offices
“The company behind Facebook, Uber and Netflix payments reveals huge transaction growth” Adyen’s total transaction volume in $ billion 300 225 "Adyen is the best fit for global merchants 150 that want to increase their overall payments performance, reduce their fraud rates and simplify their overall 75 payments operations” 0 2012 2013 2014 2015 2016 2017 2018 2019
The Adyen Way of Engineering We prioritize current merchant experience We all make mistakes, but we seek help over future features as soon as we find out You own when, where and how To think like the merchant we your code goes live go meet them Your code should be understandable We design for 20x at 4am under stress We embrace new technology Expose your work early when it has clear benefits We are all designers , architects , Our tech stack is open source or built in-house coders , testers , security officers and operations engineers
The Adyen Way of Engineering We prioritize current merchant experience We all make mistakes, but we seek help over future features as soon as we find out You own when, where and how To think like the merchant we your code goes live go meet them Your code should be understandable We design for 20x We design for 20x at 4am under stress We embrace new technology Expose your work early when it has clear benefits We are all designers , architects , Our tech stack is open source or built in-house coders , testers , security officers and operations engineers
The Adyen Way of Engineering We prioritize current merchant experience We all make mistakes, but we seek help over future features as soon as we find out You own when, where and how To think like the merchant we your code goes live go meet them Your code should be understandable We design for 20x at 4am under stress We embrace new technology Expose your work early Expose your work early when it has clear benefits We are all designers , architects , Our tech stack is open source or built in-house coders , testers , security officers and operations engineers
The Adyen Way of Engineering We prioritize current merchant experience We all make mistakes, but we seek help over future features as soon as we find out You own when, where and how To think like the merchant we your code goes live go meet them Your code should be understandable We design for 20x at 4am under stress We embrace new technology Expose your work early when it has clear benefits We are all designers , architects , Our tech stack is open source or built in-house Our tech stack is open source or built in-house coders , testers , security officers and operations engineers
The Adyen Way of Engineering We prioritize current merchant experience We all make mistakes, but we seek help over future features as soon as we find out You own when, where and how To think like the merchant we your code goes live go meet them Your code should be understandable We design for 20x at 4am under stress We embrace new technology Expose your work early when it has clear benefits We are all designers , architects , Our tech stack is open source or built in-house coders , testers , security officers and operations engineers
High-Level Architecture (Bibit / pre-Adyen) Public API app servers Shopper payment flow, Risk analysis, Payment authorization Reconciliation, Reporting DB main accounting database
High-Level Architecture (pre-Adyen) Public API app servers ??? ??? DB main accounting database
High-Level Architecture (pre-Adyen) Public API app servers Availability Consistency DB main accounting database
Design for Breakage
High-Level Architecture (first years) Public API app servers Stateless Asynch queues accounting app servers Statefull main accounting database DB
Front-end Maintenance
Database Maintenance
High-Level Architecture (first years) Public API app servers Stateless accounting app servers Statefull main accounting database DB
Consequences of being Stateless Statefull Public API app servers Stateless Async Notification accounting app Statefull main accounting DB
Consequences of being Stateless Refunds Request: { "merchantAccount" : "TestMerchant", "modi fi cationAmount" : { "value" : 500, "currency" : "EUR" }, "originalReference" : "9313547924770610", "reference" : "YourModi fi cationReference" } Response: { "pspReference" : "8312534564722331", "response" : "[refund-received]" }
Architecture Diagram – Authorisations Notification Risk Shopper DNA PAL Soap (XML) Recharge Vault REST (HTTP POST or JSON) Merchant ACM Soap (XML) Acquiring Network Accounting HPP PSP Data Warehouse Customer Notification Banking Network
The Challenge Public API app servers accounting app servers main accounting database DB
Growing Exponentially over $100b processed annually +
Scalability Challenges API (micro)services designed to be highly redundant and stateless. Scale linearly with more hardware. However main payment accounting system was running > 70TB on a single PostgreSQL instance at up to 25k tps. At 2-4x, optimisation and/or bigger hardware solve the problem. At 20x this is no longer sufficient and requires re- architecting.
Marbles
Generating Reports/Batch Files
The Solution / The NEW Challenge front end app servers (public API) multiple accounting clusters DB DB DB
More jars…
PspReference Refunds Request: { "merchantAccount" : "TestMerchant", "modi fi cationAmount" : { "value" : 500, "currency" : "EUR" }, "originalReference" : "93 1 3547924770610", "reference" : "YourModi fi cationReference" } Response: { "pspReference" : "8312534564722331", "response" : "[refund-received]" }
Streaming Framework Accounting DB’s should be insert only Reduce I/O and CPU in the main DB (cache thrashing / spilling to disk) Exactly once delivery (Kafka started to support this since 2017) Prevent multi-shard queries
"@type" : "com.adyen.protocol.stream.journalstream.JournalStreamItem", 1 "journalStreamItemType" : "Journal", 2 "journal" : { 3 "bookingDate" : 1493908683696, 4 "journalId" : 227274316270, 5 "postDate" : 1493908682341, 6 "lines" : [ 7 Stream { 8 "registerTypeId" : 23 , 9 "quantity" : 10500, 10 Contents "accountId" : 378293 , 11 "batch" : { 12 "accountId" : 378293 , 13 "periodEndDate" : 1493935200000, 14 "registerTypeId" : 23 , 15 "batchId" : 506220414 , 16 "periodBeginDate" : 1493848800000 17 }, 18 "unitId" : 840, 19 "journalLineId" : 117964524937, 20 "batchId" : 506220414 21 }, 22
Streaming is an Idempotent Log Value is a byte array Sequence generated by stream on which contains the raw insert; identifies offset data StreamId Key Value 1 aa ba94c3… 2 ab 8d3ffc… Stream Unique key provided by 3 ad 457e18… producer to prevent duplicates; allows idempotency 4 ba cc78c2… (exactly once delivery) … … …
A stream consists of multiple partitions Producer 1 Producer 2 Producer 3 Streaming cluster Partition 1 Partition 2 Partition 3 Consumer 1 Consumer 2 Consumer 3 Consumer 4
Streamreader hides complexity of reading partitions Streaming cluster Partition 1 Partition 2 Partition 3 Consumer Streamreader Auto-discovery of partitions by streamreader Single stream Partition readers of records Partitionreaders keep track of position and deserialize items consumer
Extend AbstractConsumer to implement a new consumer AbstractConsumer communicates with streamreader and keeps track of consumerState Consumer Streamreader Consumer database AbstractConsumer poll() Consumer- abstract void consume(records) State abstract boolean shouldPersist() abstract PersistFunction persist() persistInternal() YourConsumer (extends AbstractConsumer) Does not block consuming (asynchronous)
Recommend
More recommend