mirror of
https://github.com/Vonng/ddia.git
synced 2025-09-26 23:09:18 +08:00
add init translation
This commit is contained in:
parent
ee24fa2864
commit
003fb7a32e
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 设计数据密集型应用
|
||||
title: 设计数据密集型应用(第二版)
|
||||
linkTitle: DDIA
|
||||
cascade:
|
||||
type: docs
|
||||
@ -19,7 +19,7 @@ PostgreSQL 专家,数据库老司机,云计算泥石流。
|
||||
**校订**: [@yingang](https://github.com/yingang) | [繁體中文](/tw) **版本维护** by [@afunTW](https://github.com/afunTW) | [完整贡献者列表](/contrib)
|
||||
|
||||
> [!NOTE]
|
||||
> DDIA [**第二版**](/v2) 正在翻译中 ([`content/v2`](https://github.com/Vonng/ddia/tree/main) 目录),欢迎加入并提出您的宝贵意见!
|
||||
> DDIA [**第二版**](/v2) 正在翻译中 ([`v2/v2`](https://github.com/Vonng/ddia/tree/main) 目录),欢迎加入并提出您的宝贵意见!
|
||||
|
||||
|
||||
|
||||
|
@ -434,17 +434,18 @@ CPU、内存和磁盘已经变得更大、更快、更可靠。与单节点数
|
||||
|
||||
### 参考
|
||||
|
||||
|
||||
[^1]: Richard T. Kouzes, Gordon A. Anderson, Stephen T. Elbert, Ian Gorton, and Deborah K. Gracio. [The Changing Paradigm of Data-Intensive Computing](http://www2.ic.uff.br/~boeres/slides_AP/papers/TheChanginParadigmDataIntensiveComputing_2009.pdf). *IEEE Computer*, volume 42, issue 1, January 2009. [doi:10.1109/MC.2009.26](https://doi.org/10.1109/MC.2009.26)
|
||||
[^2]: Martin Kleppmann, Adam Wiggins, Peter van Hardenberg, and Mark McGranaghan. [Local-first software: you own your data, in spite of the cloud](https://www.inkandswitch.com/local-first/). At *2019 ACM SIGPLAN International Symposium on New Ideas, New Paradigms, and Reflections on Programming and Software* (Onward!), October 2019. [doi:10.1145/3359591.3359737](https://doi.org/10.1145/3359591.3359737)
|
||||
[^3]: Joe Reis and Matt Housley. [*Fundamentals of Data Engineering*](https://www.oreilly.com/library/view/fundamentals-of-data/9781098108298/). O'Reilly Media, 2022. ISBN: 9781098108304
|
||||
[^4]: Rui Pedro Machado and Helder Russa. [*Analytics Engineering with SQL and dbt*](https://www.oreilly.com/library/view/analytics-engineering-with/9781098142377/). O'Reilly Media, 2023. ISBN: 9781098142384
|
||||
[^3]: Joe Reis and Matt Housley. [*Fundamentals of Data Engineering*](https://www.oreilly.com/library/view/fundamentals-of-data/9781098108298/). O’Reilly Media, 2022. ISBN: 9781098108304
|
||||
[^4]: Rui Pedro Machado and Helder Russa. [*Analytics Engineering with SQL and dbt*](https://www.oreilly.com/library/view/analytics-engineering-with/9781098142377/). O’Reilly Media, 2023. ISBN: 9781098142384
|
||||
[^5]: Edgar F. Codd, S. B. Codd, and C. T. Salley. [Providing OLAP to User-Analysts: An IT Mandate](https://www.estgv.ipv.pt/PaginasPessoais/jloureiro/ESI_AID2007_2008/fichas/codd.pdf). E. F. Codd Associates, 1993. Archived at [perma.cc/RKX8-2GEE](https://perma.cc/RKX8-2GEE)
|
||||
[^6]: Chinmay Soman and Neha Pawar. [Comparing Three Real-Time OLAP Databases: Apache Pinot, Apache Druid, and ClickHouse](https://startree.ai/blog/a-tale-of-three-real-time-olap-databases). *startree.ai*, April 2023. Archived at [perma.cc/8BZP-VWPA](https://perma.cc/8BZP-VWPA)
|
||||
[^7]: Surajit Chaudhuri and Umeshwar Dayal. [An Overview of Data Warehousing and OLAP Technology](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/sigrecord.pdf). *ACM SIGMOD Record*, volume 26, issue 1, pages 65–74, March 1997. [doi:10.1145/248603.248616](https://doi.org/10.1145/248603.248616)
|
||||
[^8]: Fatma Özcan, Yuanyuan Tian, and Pinar Tözün. [Hybrid Transactional/Analytical Processing: A Survey](https://humming80.github.io/papers/sigmod-htaptut.pdf). At *ACM International Conference on Management of Data* (SIGMOD), May 2017. [doi:10.1145/3035918.3054784](https://doi.org/10.1145/3035918.3054784)
|
||||
[^9]: Adam Prout, Szu-Po Wang, Joseph Victor, Zhou Sun, Yongzhu Li, Jack Chen, Evan Bergeron, Eric Hanson, Robert Walzer, Rodrigo Gomes, and Nikita Shamgunov. [Cloud-Native Transactions and Analytics in SingleStore](https://dl.acm.org/doi/abs/10.1145/3514221.3526055). At *International Conference on Management of Data* (SIGMOD), June 2022. [doi:10.1145/3514221.3526055](https://doi.org/10.1145/3514221.3526055)
|
||||
[^10]: Chao Zhang, Guoliang Li, Jintao Zhang, Xinning Zhang, and Jianhua Feng. [HTAP Databases: A Survey](https://arxiv.org/pdf/2404.15670). *IEEE Transactions on Knowledge and Data Engineering*, April 2024. [doi:10.1109/TKDE.2024.3389693](https://doi.org/10.1109/TKDE.2024.3389693)
|
||||
[^11]: Michael Stonebraker and Uğur Çetintemel. ['One Size Fits All': An Idea Whose Time Has Come and Gone](https://pages.cs.wisc.edu/~shivaram/cs744-readings/fits_all.pdf). At *21st International Conference on Data Engineering* (ICDE), April 2005. [doi:10.1109/ICDE.2005.1](https://doi.org/10.1109/ICDE.2005.1)
|
||||
[^11]: Michael Stonebraker and Uğur Çetintemel. [‘One Size Fits All’: An Idea Whose Time Has Come and Gone](https://pages.cs.wisc.edu/~shivaram/cs744-readings/fits_all.pdf). At *21st International Conference on Data Engineering* (ICDE), April 2005. [doi:10.1109/ICDE.2005.1](https://doi.org/10.1109/ICDE.2005.1)
|
||||
[^12]: Jeffrey Cohen, Brian Dolan, Mark Dunlap, Joseph M. Hellerstein, and Caleb Welton. [MAD Skills: New Analysis Practices for Big Data](https://www.vldb.org/pvldb/vol2/vldb09-219.pdf). *Proceedings of the VLDB Endowment*, volume 2, issue 2, pages 1481–1492, August 2009. [doi:10.14778/1687553.1687576](https://doi.org/10.14778/1687553.1687576)
|
||||
[^13]: Dan Olteanu. [The Relational Data Borg is Learning](https://www.vldb.org/pvldb/vol13/p3502-olteanu.pdf). *Proceedings of the VLDB Endowment*, volume 13, issue 12, August 2020. [doi:10.14778/3415478.3415572](https://doi.org/10.14778/3415478.3415572)
|
||||
[^14]: Matt Bornstein, Martin Casado, and Jennifer Li. [Emerging Architectures for Modern Data Infrastructure: 2020](https://future.a16z.com/emerging-architectures-for-modern-data-infrastructure-2020/). *future.a16z.com*, October 2020. Archived at [perma.cc/LF8W-KDCC](https://perma.cc/LF8W-KDCC)
|
||||
@ -452,10 +453,10 @@ CPU、内存和磁盘已经变得更大、更快、更可靠。与单节点数
|
||||
[^16]: Bobby Johnson and Joseph Adler. [The Sushi Principle: Raw Data Is Better](https://learning.oreilly.com/videos/strata-hadoop/9781491924143/9781491924143-video210840/). At *Strata+Hadoop World*, February 2015.
|
||||
[^17]: Michael Armbrust, Ali Ghodsi, Reynold Xin, and Matei Zaharia. [Lakehouse: A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics](https://www.cidrdb.org/cidr2021/papers/cidr2021_paper17.pdf). At *11th Annual Conference on Innovative Data Systems Research* (CIDR), January 2021.
|
||||
[^18]: DataKitchen, Inc. [The DataOps Manifesto](https://dataopsmanifesto.org/en/). *dataopsmanifesto.org*, 2017. Archived at [perma.cc/3F5N-FUQ4](https://perma.cc/3F5N-FUQ4)
|
||||
[^19]: Tejas Manohar. [What is Reverse ETL: A Definition & Why It's Taking Off](https://hightouch.io/blog/reverse-etl/). *hightouch.io*, November 2021. Archived at [perma.cc/A7TN-GLYJ](https://perma.cc/A7TN-GLYJ)
|
||||
[^20]: Simon O'Regan. [Designing Data Products](https://towardsdatascience.com/designing-data-products-b6b93edf3d23). *towardsdatascience.com*, August 2018. Archived at [perma.cc/HU67-3RV8](https://perma.cc/HU67-3RV8)
|
||||
[^19]: Tejas Manohar. [What is Reverse ETL: A Definition & Why It’s Taking Off](https://hightouch.io/blog/reverse-etl/). *hightouch.io*, November 2021. Archived at [perma.cc/A7TN-GLYJ](https://perma.cc/A7TN-GLYJ)
|
||||
[^20]: Simon O’Regan. [Designing Data Products](https://towardsdatascience.com/designing-data-products-b6b93edf3d23). *towardsdatascience.com*, August 2018. Archived at [perma.cc/HU67-3RV8](https://perma.cc/HU67-3RV8)
|
||||
[^21]: Camille Fournier. [Why is it so hard to decide to buy?](https://skamille.medium.com/why-is-it-so-hard-to-decide-to-buy-d86fee98e88e) *skamille.medium.com*, July 2021. Archived at [perma.cc/6VSG-HQ5X](https://perma.cc/6VSG-HQ5X)
|
||||
[^22]: David Heinemeier Hansson. [Why we're leaving the cloud](https://world.hey.com/dhh/why-we-re-leaving-the-cloud-654b47e0). *world.hey.com*, October 2022. Archived at [perma.cc/82E6-UJ65](https://perma.cc/82E6-UJ65)
|
||||
[^22]: David Heinemeier Hansson. [Why we’re leaving the cloud](https://world.hey.com/dhh/why-we-re-leaving-the-cloud-654b47e0). *world.hey.com*, October 2022. Archived at [perma.cc/82E6-UJ65](https://perma.cc/82E6-UJ65)
|
||||
[^23]: Nima Badizadegan. [Use One Big Server](https://specbranch.com/posts/one-big-server/). *specbranch.com*, August 2022. Archived at [perma.cc/M8NB-95UK](https://perma.cc/M8NB-95UK)
|
||||
[^24]: Steve Yegge. [Dear Google Cloud: Your Deprecation Policy is Killing You](https://steve-yegge.medium.com/dear-google-cloud-your-deprecation-policy-is-killing-you-ee7525dc05dc). *steve-yegge.medium.com*, August 2020. Archived at [perma.cc/KQP9-SPGU](https://perma.cc/KQP9-SPGU)
|
||||
[^25]: Alexandre Verbitski, Anurag Gupta, Debanjan Saha, Murali Brahmadesam, Kamal Gupta, Raman Mittal, Sailesh Krishnamurthy, Sandor Maurice, Tengiz Kharatishvili, and Xiaofeng Bao. [Amazon Aurora: Design Considerations for High Throughput Cloud-Native Relational Databases](https://media.amazonwebservices.com/blog/2017/aurora-design-considerations-paper.pdf). At *ACM International Conference on Management of Data* (SIGMOD), pages 1041–1052, May 2017. [doi:10.1145/3035918.3056101](https://doi.org/10.1145/3035918.3056101)
|
||||
@ -467,11 +468,11 @@ CPU、内存和磁盘已经变得更大、更快、更可靠。与单节点数
|
||||
[^31]: Ravi Murthy and Gurmeet Goindi. [AlloyDB for PostgreSQL under the hood: Intelligent, database-aware storage](https://cloud.google.com/blog/products/databases/alloydb-for-postgresql-intelligent-scalable-storage). *cloud.google.com*, May 2022. Archived at [archive.org](https://web.archive.org/web/20220514021120/https%3A//cloud.google.com/blog/products/databases/alloydb-for-postgresql-intelligent-scalable-storage)
|
||||
[^32]: Jack Vanlightly. [The Architecture of Serverless Data Systems](https://jack-vanlightly.com/blog/2023/11/14/the-architecture-of-serverless-data-systems). *jack-vanlightly.com*, November 2023. Archived at [perma.cc/UDV4-TNJ5](https://perma.cc/UDV4-TNJ5)
|
||||
[^33]: Eric Jonas, Johann Schleier-Smith, Vikram Sreekanti, Chia-Che Tsai, Anurag Khandelwal, Qifan Pu, Vaishaal Shankar, Joao Carreira, Karl Krauth, Neeraja Yadwadkar, Joseph E. Gonzalez, Raluca Ada Popa, Ion Stoica, David A. Patterson. [Cloud Programming Simplified: A Berkeley View on Serverless Computing](https://arxiv.org/abs/1902.03383). *arxiv.org*, February 2019.
|
||||
[^34]: Betsy Beyer, Jennifer Petoff, Chris Jones, and Niall Richard Murphy. [*Site Reliability Engineering: How Google Runs Production Systems*](https://www.oreilly.com/library/view/site-reliability-engineering/9781491929117/). O'Reilly Media, 2016. ISBN: 9781491929124
|
||||
[^34]: Betsy Beyer, Jennifer Petoff, Chris Jones, and Niall Richard Murphy. [*Site Reliability Engineering: How Google Runs Production Systems*](https://www.oreilly.com/library/view/site-reliability-engineering/9781491929117/). O’Reilly Media, 2016. ISBN: 9781491929124
|
||||
[^35]: Thomas Limoncelli. [The Time I Stole $10,000 from Bell Labs](https://queue.acm.org/detail.cfm?id=3434773). *ACM Queue*, volume 18, issue 5, November 2020. [doi:10.1145/3434571.3434773](https://doi.org/10.1145/3434571.3434773)
|
||||
[^36]: Charity Majors. [The Future of Ops Jobs](https://acloudguru.com/blog/engineering/the-future-of-ops-jobs). *acloudguru.com*, August 2020. Archived at [perma.cc/GRU2-CZG3](https://perma.cc/GRU2-CZG3)
|
||||
[^37]: Boris Cherkasky. [(Over)Pay As You Go for Your Datastore](https://medium.com/riskified-technology/over-pay-as-you-go-for-your-datastore-11a29ae49a8b). *medium.com*, September 2021. Archived at [perma.cc/Q8TV-2AM2](https://perma.cc/Q8TV-2AM2)
|
||||
[^38]: Shlomi Kushchi. [Serverless Doesn't Mean DevOpsLess or NoOps](https://thenewstack.io/serverless-doesnt-mean-devopsless-or-noops/). *thenewstack.io*, February 2023. Archived at [perma.cc/3NJR-AYYU](https://perma.cc/3NJR-AYYU)
|
||||
[^38]: Shlomi Kushchi. [Serverless Doesn’t Mean DevOpsLess or NoOps](https://thenewstack.io/serverless-doesnt-mean-devopsless-or-noops/). *thenewstack.io*, February 2023. Archived at [perma.cc/3NJR-AYYU](https://perma.cc/3NJR-AYYU)
|
||||
[^39]: Erik Bernhardsson. [Storm in the stratosphere: how the cloud will be reshuffled](https://erikbern.com/2021/11/30/storm-in-the-stratosphere-how-the-cloud-will-be-reshuffled.html). *erikbern.com*, November 2021. Archived at [perma.cc/SYB2-99P3](https://perma.cc/SYB2-99P3)
|
||||
[^40]: Benn Stancil. [The data OS](https://benn.substack.com/p/the-data-os). *benn.substack.com*, September 2021. Archived at [perma.cc/WQ43-FHS6](https://perma.cc/WQ43-FHS6)
|
||||
[^41]: Maria Korolov. [Data residency laws pushing companies toward residency as a service](https://www.csoonline.com/article/3647761/data-residency-laws-pushing-companies-toward-residency-as-a-service.html). *csoonline.com*, January 2022. Archived at [perma.cc/CHE4-XZZ2](https://perma.cc/CHE4-XZZ2)
|
||||
@ -480,20 +481,20 @@ CPU、内存和磁盘已经变得更大、更快、更可靠。与单节点数
|
||||
[^44]: Kousik Nath. [These are the numbers every computer engineer should know](https://www.freecodecamp.org/news/must-know-numbers-for-every-computer-engineer/). *freecodecamp.org*, September 2019. Archived at [perma.cc/RW73-36RL](https://perma.cc/RW73-36RL)
|
||||
[^45]: Joseph M. Hellerstein, Jose Faleiro, Joseph E. Gonzalez, Johann Schleier-Smith, Vikram Sreekanti, Alexey Tumanov, and Chenggang Wu. [Serverless Computing: One Step Forward, Two Steps Back](https://arxiv.org/abs/1812.03651). At *Conference on Innovative Data Systems Research* (CIDR), January 2019.
|
||||
[^46]: Frank McSherry, Michael Isard, and Derek G. Murray. [Scalability! But at What COST?](https://www.usenix.org/system/files/conference/hotos15/hotos15-paper-mcsherry.pdf) At *15th USENIX Workshop on Hot Topics in Operating Systems* (HotOS), May 2015.
|
||||
[^47]: Cindy Sridharan. *[Distributed Systems Observability: A Guide to Building Robust Systems](https://unlimited.humio.com/rs/756-LMY-106/images/Distributed-Systems-Observability-eBook.pdf)*. Report, O'Reilly Media, May 2018. Archived at [perma.cc/M6JL-XKCM](https://perma.cc/M6JL-XKCM)
|
||||
[^47]: Cindy Sridharan. *[Distributed Systems Observability: A Guide to Building Robust Systems](https://unlimited.humio.com/rs/756-LMY-106/images/Distributed-Systems-Observability-eBook.pdf)*. Report, O’Reilly Media, May 2018. Archived at [perma.cc/M6JL-XKCM](https://perma.cc/M6JL-XKCM)
|
||||
[^48]: Charity Majors. [Observability — A 3-Year Retrospective](https://thenewstack.io/observability-a-3-year-retrospective/). *thenewstack.io*, August 2019. Archived at [perma.cc/CG62-TJWL](https://perma.cc/CG62-TJWL)
|
||||
[^49]: Benjamin H. Sigelman, Luiz André Barroso, Mike Burrows, Pat Stephenson, Manoj Plakal, Donald Beaver, Saul Jaspan, and Chandan Shanbhag. [Dapper, a Large-Scale Distributed Systems Tracing Infrastructure](https://research.google/pubs/pub36356/). Google Technical Report dapper-2010-1, April 2010. Archived at [perma.cc/K7KU-2TMH](https://perma.cc/K7KU-2TMH)
|
||||
[^50]: Rodrigo Laigner, Yongluan Zhou, Marcos Antonio Vaz Salles, Yijian Liu, and Marcos Kalinowski. [Data management in microservices: State of the practice, challenges, and research directions](https://www.vldb.org/pvldb/vol14/p3348-laigner.pdf). *Proceedings of the VLDB Endowment*, volume 14, issue 13, pages 3348–3361, September 2021. [doi:10.14778/3484224.3484232](https://doi.org/10.14778/3484224.3484232)
|
||||
[^51]: Jordan Tigani. [Big Data is Dead](https://motherduck.com/blog/big-data-is-dead/). *motherduck.com*, February 2023. Archived at [perma.cc/HT4Q-K77U](https://perma.cc/HT4Q-K77U)
|
||||
[^52]: Sam Newman. [*Building Microservices*, second edition](https://www.oreilly.com/library/view/building-microservices-2nd/9781492034018/). O'Reilly Media, 2021. ISBN: 9781492034025
|
||||
[^52]: Sam Newman. [*Building Microservices*, second edition](https://www.oreilly.com/library/view/building-microservices-2nd/9781492034018/). O’Reilly Media, 2021. ISBN: 9781492034025
|
||||
[^53]: Chris Richardson. [Microservices: Decomposing Applications for Deployability and Scalability](https://www.infoq.com/articles/microservices-intro/). *infoq.com*, May 2014. Archived at [perma.cc/CKN4-YEQ2](https://perma.cc/CKN4-YEQ2)
|
||||
[^54]: Mohammad Shahrad, Rodrigo Fonseca, Íñigo Goiri, Gohar Chaudhry, Paul Batum, Jason Cooke, Eduardo Laureano, Colby Tresness, Mark Russinovich, Ricardo Bianchini. [Serverless in the Wild: Characterizing and Optimizing the Serverless Workload at a Large Cloud Provider](https://www.usenix.org/system/files/atc20-shahrad.pdf). At *USENIX Annual Technical Conference* (ATC), July 2020.
|
||||
[^55]: Luiz André Barroso, Urs Hölzle, and Parthasarathy Ranganathan. [The Datacenter as a Computer: Designing Warehouse-Scale Machines](https://www.morganclaypool.com/doi/10.2200/S00874ED3V01Y201809CAC046), third edition. Morgan & Claypool Synthesis Lectures on Computer Architecture, October 2018. [doi:10.2200/S00874ED3V01Y201809CAC046](https://doi.org/10.2200/S00874ED3V01Y201809CAC046)
|
||||
[^56]: David Fiala, Frank Mueller, Christian Engelmann, Rolf Riesen, Kurt Ferreira, and Ron Brightwell. [Detection and Correction of Silent Data Corruption for Large-Scale High-Performance Computing](https://arcb.csc.ncsu.edu/~mueller/ftp/pub/mueller/papers/sc12.pdf)," at *International Conference for High Performance Computing, Networking, Storage and Analysis* (SC), November 2012. [doi:10.1109/SC.2012.49](https://doi.org/10.1109/SC.2012.49)
|
||||
[^56]: David Fiala, Frank Mueller, Christian Engelmann, Rolf Riesen, Kurt Ferreira, and Ron Brightwell. [Detection and Correction of Silent Data Corruption for Large-Scale High-Performance Computing](https://arcb.csc.ncsu.edu/~mueller/ftp/pub/mueller/papers/sc12.pdf),” at *International Conference for High Performance Computing, Networking, Storage and Analysis* (SC), November 2012. [doi:10.1109/SC.2012.49](https://doi.org/10.1109/SC.2012.49)
|
||||
[^57]: Anna Kornfeld Simpson, Adriana Szekeres, Jacob Nelson, and Irene Zhang. [Securing RDMA for High-Performance Datacenter Storage Systems](https://www.usenix.org/conference/hotcloud20/presentation/kornfeld-simpson). At *12th USENIX Workshop on Hot Topics in Cloud Computing* (HotCloud), July 2020.
|
||||
[^58]: Arjun Singh, Joon Ong, Amit Agarwal, Glen Anderson, Ashby Armistead, Roy Bannon, Seb Boving, Gaurav Desai, Bob Felderman, Paulie Germano, Anand Kanagala, Jeff Provost, Jason Simmons, Eiichi Tanda, Jim Wanderer, Urs Hölzle, Stephen Stuart, and Amin Vahdat. [Jupiter Rising: A Decade of Clos Topologies and Centralized Control in Google's Datacenter Network](https://conferences.sigcomm.org/sigcomm/2015/pdf/papers/p183.pdf). At *Annual Conference of the ACM Special Interest Group on Data Communication* (SIGCOMM), August 2015. [doi:10.1145/2785956.2787508](https://doi.org/10.1145/2785956.2787508)
|
||||
[^59]: Glenn K. Lockwood. [Hadoop's Uncomfortable Fit in HPC](https://blog.glennklockwood.com/2014/05/hadoops-uncomfortable-fit-in-hpc.html). *glennklockwood.blogspot.co.uk*, May 2014. Archived at [perma.cc/S8XX-Y67B](https://perma.cc/S8XX-Y67B)
|
||||
[^60]: Cathy O'Neil: *Weapons of Math Destruction: How Big Data Increases Inequality and Threatens Democracy*. Crown Publishing, 2016. ISBN: 9780553418811
|
||||
[^58]: Arjun Singh, Joon Ong, Amit Agarwal, Glen Anderson, Ashby Armistead, Roy Bannon, Seb Boving, Gaurav Desai, Bob Felderman, Paulie Germano, Anand Kanagala, Jeff Provost, Jason Simmons, Eiichi Tanda, Jim Wanderer, Urs Hölzle, Stephen Stuart, and Amin Vahdat. [Jupiter Rising: A Decade of Clos Topologies and Centralized Control in Google’s Datacenter Network](https://conferences.sigcomm.org/sigcomm/2015/pdf/papers/p183.pdf). At *Annual Conference of the ACM Special Interest Group on Data Communication* (SIGCOMM), August 2015. [doi:10.1145/2785956.2787508](https://doi.org/10.1145/2785956.2787508)
|
||||
[^59]: Glenn K. Lockwood. [Hadoop’s Uncomfortable Fit in HPC](https://blog.glennklockwood.com/2014/05/hadoops-uncomfortable-fit-in-hpc.html). *glennklockwood.blogspot.co.uk*, May 2014. Archived at [perma.cc/S8XX-Y67B](https://perma.cc/S8XX-Y67B)
|
||||
[^60]: Cathy O’Neil: *Weapons of Math Destruction: How Big Data Increases Inequality and Threatens Democracy*. Crown Publishing, 2016. ISBN: 9780553418811
|
||||
[^61]: Supreeth Shastri, Vinay Banakar, Melissa Wasserman, Arun Kumar, and Vijay Chidambaram. [Understanding and Benchmarking the Impact of GDPR on Database Systems](https://www.vldb.org/pvldb/vol13/p1064-shastri.pdf). *Proceedings of the VLDB Endowment*, volume 13, issue 7, pages 1064–1077, March 2020. [doi:10.14778/3384345.3384354](https://doi.org/10.14778/3384345.3384354)
|
||||
[^62]: Martin Fowler. [Datensparsamkeit](https://www.martinfowler.com/bliki/Datensparsamkeit.html). *martinfowler.com*, December 2013. Archived at [perma.cc/R9QX-CME6](https://perma.cc/R9QX-CME6)
|
||||
[^63]: [Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 (General Data Protection Regulation)](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679&from=EN). *Official Journal of the European Union* L 119/1, May 2016.
|
||||
[^63]: [Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 (General Data Protection Regulation)](https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679&from=EN). *Official Journal of the European Union* L 119/1, May 2016.
|
||||
|
1546
content/zh/ch10.md
1546
content/zh/ch10.md
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "第十一章:批处理"
|
||||
linkTitle: "10. 批处理"
|
||||
weight: 310
|
||||
linkTitle: "11. 批处理"
|
||||
weight: 311
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "第十二章:流处理"
|
||||
linkTitle: "11. 流处理"
|
||||
weight: 311
|
||||
linkTitle: "12. 流处理"
|
||||
weight: 312
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "第十三章:数据系统的未来"
|
||||
linkTitle: "13. 数据系统的未来"
|
||||
weight: 312
|
||||
weight: 313
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||
|
@ -4,6 +4,8 @@ weight: 102
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||

|
||||
|
||||
> *互联网做得如此之好,以至于大多数人认为它是一种自然资源,就像太平洋一样,而不是人造的东西。上一次有这种规模的技术如此没有错误是什么时候?*
|
||||
>
|
||||
> [Alan Kay](https://www.drdobbs.com/architecture-and-design/interview-with-alan-kay/240003442),
|
||||
@ -392,103 +394,104 @@ Akamai 最近的一项研究 [^24] 声称响应时间增加 100 毫秒使电子
|
||||
|
||||
最后,我们研究了可维护性的几个方面,包括支持运维团队的工作、管理复杂性以及使应用程序的功能随着时间的推移易于发展。关于如何实现这些事情没有简单的答案,但有一件事可以帮助,那就是使用经过验证在实践中有价值的易于理解的构建块来构建应用程序。本书的其余部分将涵盖一系列已被证明在实践中有价值的构建块。
|
||||
|
||||
|
||||
### 参考
|
||||
|
||||
[^1]: Mike Cvet. [How We Learned to Stop Worrying and Love Fan-In at Twitter](https://www.youtube.com/watch?v=WEgCjwyXvwc). At *QCon San Francisco*, December 2016.
|
||||
[^2]: Raffi Krikorian. [Timelines at Scale](https://www.infoq.com/presentations/Twitter-Timeline-Scalability/). At *QCon San Francisco*, November 2012. Archived at [perma.cc/V9G5-KLYK](https://perma.cc/V9G5-KLYK)
|
||||
[^3]: Twitter. [Twitter's Recommendation Algorithm](https://blog.twitter.com/engineering/en_us/topics/open-source/2023/twitter-recommendation-algorithm). *blog.twitter.com*, March 2023. Archived at [perma.cc/L5GT-229T](https://perma.cc/L5GT-229T)
|
||||
[^4]: Raffi Krikorian. [New Tweets per second record, and how!](https://blog.twitter.com/engineering/en_us/a/2013/new-tweets-per-second-record-and-how) *blog.twitter.com*, August 2013. Archived at [perma.cc/6JZN-XJYN](https://perma.cc/6JZN-XJYN)
|
||||
[^5]: Jaz Volpert. [When Imperfect Systems are Good, Actually: Bluesky's Lossy Timelines](https://jazco.dev/2025/02/19/imperfection/). *jazco.dev*, February 2025. Archived at [perma.cc/2PVE-L2MX](https://perma.cc/2PVE-L2MX)
|
||||
[^6]: Samuel Axon. [3% of Twitter's Servers Dedicated to Justin Bieber](https://mashable.com/archive/justin-bieber-twitter). *mashable.com*, September 2010. Archived at [perma.cc/F35N-CGVX](https://perma.cc/F35N-CGVX)
|
||||
[^7]: Nathan Bronson, Abutalib Aghayev, Aleksey Charapko, and Timothy Zhu. [Metastable Failures in Distributed Systems](https://sigops.org/s/conferences/hotos/2021/papers/hotos21-s11-bronson.pdf). At *Workshop on Hot Topics in Operating Systems* (HotOS), May 2021. [doi:10.1145/3458336.3465286](https://doi.org/10.1145/3458336.3465286)
|
||||
[^8]: Marc Brooker. [Metastability and Distributed Systems](https://brooker.co.za/blog/2021/05/24/metastable.html). *brooker.co.za*, May 2021. Archived at [perma.cc/7FGJ-7XRK](https://perma.cc/7FGJ-7XRK)
|
||||
[^9]: Marc Brooker. [Exponential Backoff And Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/). *aws.amazon.com*, March 2015. Archived at [perma.cc/R6MS-AZKH](https://perma.cc/R6MS-AZKH)
|
||||
[^10]: Marc Brooker. [What is Backoff For?](https://brooker.co.za/blog/2022/08/11/backoff.html) *brooker.co.za*, August 2022. Archived at [perma.cc/PW9N-55Q5](https://perma.cc/PW9N-55Q5)
|
||||
[^11]: Michael T. Nygard. [*Release It!*](https://learning.oreilly.com/library/view/release-it-2nd/9781680504552/), 2nd Edition. Pragmatic Bookshelf, January 2018. ISBN: 9781680502398
|
||||
[^12]: Frank Chen. [Slowing Down to Speed Up – Circuit Breakers for Slack's CI/CD](https://slack.engineering/circuit-breakers/). *slack.engineering*, August 2022. Archived at [perma.cc/5FGS-ZPH3](https://perma.cc/5FGS-ZPH3)
|
||||
[^13]: Marc Brooker. [Fixing retries with token buckets and circuit breakers](https://brooker.co.za/blog/2022/02/28/retries.html). *brooker.co.za*, February 2022. Archived at [perma.cc/MD6N-GW26](https://perma.cc/MD6N-GW26)
|
||||
[^14]: David Yanacek. [Using load shedding to avoid overload](https://aws.amazon.com/builders-library/using-load-shedding-to-avoid-overload/). Amazon Builders' Library, *aws.amazon.com*. Archived at [perma.cc/9SAW-68MP](https://perma.cc/9SAW-68MP)
|
||||
[^15]: Matthew Sackman. [Pushing Back](https://wellquite.org/posts/lshift/pushing_back/). *wellquite.org*, May 2016. Archived at [perma.cc/3KCZ-RUFY](https://perma.cc/3KCZ-RUFY)
|
||||
[^16]: Dmitry Kopytkov and Patrick Lee. [Meet Bandaid, the Dropbox service proxy](https://dropbox.tech/infrastructure/meet-bandaid-the-dropbox-service-proxy). *dropbox.tech*, March 2018. Archived at [perma.cc/KUU6-YG4S](https://perma.cc/KUU6-YG4S)
|
||||
[^17]: Haryadi S. Gunawi, Riza O. Suminto, Russell Sears, Casey Golliher, Swaminathan Sundararaman, Xing Lin, Tim Emami, Weiguang Sheng, Nematollah Bidokhti, Caitie McCaffrey, Gary Grider, Parks M. Fields, Kevin Harms, Robert B. Ross, Andree Jacobson, Robert Ricci, Kirk Webb, Peter Alvaro, H. Birali Runesha, Mingzhe Hao, and Huaicheng Li. [Fail-Slow at Scale: Evidence of Hardware Performance Faults in Large Production Systems](https://www.usenix.org/system/files/conference/fast18/fast18-gunawi.pdf). At *16th USENIX Conference on File and Storage Technologies*, February 2018.
|
||||
[^18]: Marc Brooker. [Is the Mean Really Useless?](https://brooker.co.za/blog/2017/12/28/mean.html) *brooker.co.za*, December 2017. Archived at [perma.cc/U5AE-CVEM](https://perma.cc/U5AE-CVEM)
|
||||
[^19]: Giuseppe DeCandia, Deniz Hastorun, Madan Jampani, Gunavardhan Kakulapati, Avinash Lakshman, Alex Pilchin, Swaminathan Sivasubramanian, Peter Vosshall, and Werner Vogels. [Dynamo: Amazon's Highly Available Key-Value Store](https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf). At *21st ACM Symposium on Operating Systems Principles* (SOSP), October 2007. [doi:10.1145/1294261.1294281](https://doi.org/10.1145/1294261.1294281)
|
||||
[^20]: Kathryn Whitenton. [The Need for Speed, 23 Years Later](https://www.nngroup.com/articles/the-need-for-speed/). *nngroup.com*, May 2020. Archived at [perma.cc/C4ER-LZYA](https://perma.cc/C4ER-LZYA)
|
||||
[^21]: Greg Linden. [Marissa Mayer at Web 2.0](https://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html). *glinden.blogspot.com*, November 2005. Archived at [perma.cc/V7EA-3VXB](https://perma.cc/V7EA-3VXB)
|
||||
[^22]: Jake Brutlag. [Speed Matters for Google Web Search](https://services.google.com/fh/files/blogs/google_delayexp.pdf). *services.google.com*, June 2009. Archived at [perma.cc/BK7R-X7M2](https://perma.cc/BK7R-X7M2)
|
||||
[^23]: Eric Schurman and Jake Brutlag. [Performance Related Changes and their User Impact](https://www.youtube.com/watch?v=bQSE51-gr2s). Talk at *Velocity 2009*.
|
||||
[^24]: Akamai Technologies, Inc. [The State of Online Retail Performance](https://web.archive.org/web/20210729180749/https%3A//www.akamai.com/us/en/multimedia/documents/report/akamai-state-of-online-retail-performance-spring-2017.pdf). *akamai.com*, April 2017. Archived at [perma.cc/UEK2-HYCS](https://perma.cc/UEK2-HYCS)
|
||||
[^25]: Xiao Bai, Ioannis Arapakis, B. Barla Cambazoglu, and Ana Freire. [Understanding and Leveraging the Impact of Response Latency on User Behaviour in Web Search](https://iarapakis.github.io/papers/TOIS17.pdf). *ACM Transactions on Information Systems*, volume 36, issue 2, article 21, April 2018. [doi:10.1145/3106372](https://doi.org/10.1145/3106372)
|
||||
[^26]: Jeffrey Dean and Luiz André Barroso. [The Tail at Scale](https://cacm.acm.org/research/the-tail-at-scale/). *Communications of the ACM*, volume 56, issue 2, pages 74–80, February 2013. [doi:10.1145/2408776.2408794](https://doi.org/10.1145/2408776.2408794)
|
||||
[^27]: Alex Hidalgo. [*Implementing Service Level Objectives: A Practical Guide to SLIs, SLOs, and Error Budgets*](https://www.oreilly.com/library/view/implementing-service-level/9781492076803/). O'Reilly Media, September 2020. ISBN: 1492076813
|
||||
[^28]: Jeffrey C. Mogul and John Wilkes. [Nines are Not Enough: Meaningful Metrics for Clouds](https://research.google/pubs/pub48033/). At *17th Workshop on Hot Topics in Operating Systems* (HotOS), May 2019. [doi:10.1145/3317550.3321432](https://doi.org/10.1145/3317550.3321432)
|
||||
[^29]: Tamás Hauer, Philipp Hoffmann, John Lunney, Dan Ardelean, and Amer Diwan. [Meaningful Availability](https://www.usenix.org/conference/nsdi20/presentation/hauer). At *17th USENIX Symposium on Networked Systems Design and Implementation* (NSDI), February 2020.
|
||||
[^30]: Ted Dunning. [The t-digest: Efficient estimates of distributions](https://www.sciencedirect.com/science/article/pii/S2665963820300403). *Software Impacts*, volume 7, article 100049, February 2021. [doi:10.1016/j.simpa.2020.100049](https://doi.org/10.1016/j.simpa.2020.100049)
|
||||
[^31]: David Kohn. [How percentile approximation works (and why it's more useful than averages)](https://www.timescale.com/blog/how-percentile-approximation-works-and-why-its-more-useful-than-averages/). *timescale.com*, September 2021. Archived at [perma.cc/3PDP-NR8B](https://perma.cc/3PDP-NR8B)
|
||||
[^32]: Heinrich Hartmann and Theo Schlossnagle. [Circllhist — A Log-Linear Histogram Data Structure for IT Infrastructure Monitoring](https://arxiv.org/pdf/2001.06561.pdf). *arxiv.org*, January 2020.
|
||||
[^33]: Charles Masson, Jee E. Rim, and Homin K. Lee. [DDSketch: A Fast and Fully-Mergeable Quantile Sketch with Relative-Error Guarantees](https://www.vldb.org/pvldb/vol12/p2195-masson.pdf). *Proceedings of the VLDB Endowment*, volume 12, issue 12, pages 2195–2205, August 2019. [doi:10.14778/3352063.3352135](https://doi.org/10.14778/3352063.3352135)
|
||||
[^34]: Baron Schwartz. [Why Percentiles Don't Work the Way You Think](https://orangematter.solarwinds.com/2016/11/18/why-percentiles-dont-work-the-way-you-think/). *solarwinds.com*, November 2016. Archived at [perma.cc/469T-6UGB](https://perma.cc/469T-6UGB)
|
||||
[^35]: Walter L. Heimerdinger and Charles B. Weinstock. [A Conceptual Framework for System Fault Tolerance](https://resources.sei.cmu.edu/asset_files/TechnicalReport/1992_005_001_16112.pdf). Technical Report CMU/SEI-92-TR-033, Software Engineering Institute, Carnegie Mellon University, October 1992. Archived at [perma.cc/GD2V-DMJW](https://perma.cc/GD2V-DMJW)
|
||||
[^36]: Felix C. Gärtner. [Fundamentals of fault-tolerant distributed computing in asynchronous environments](https://dl.acm.org/doi/pdf/10.1145/311531.311532). *ACM Computing Surveys*, volume 31, issue 1, pages 1–26, March 1999. [doi:10.1145/311531.311532](https://doi.org/10.1145/311531.311532)
|
||||
[^37]: Algirdas Avižienis, Jean-Claude Laprie, Brian Randell, and Carl Landwehr. [Basic Concepts and Taxonomy of Dependable and Secure Computing](https://hdl.handle.net/1903/6459). *IEEE Transactions on Dependable and Secure Computing*, volume 1, issue 1, January 2004. [doi:10.1109/TDSC.2004.2](https://doi.org/10.1109/TDSC.2004.2)
|
||||
[^38]: Ding Yuan, Yu Luo, Xin Zhuang, Guilherme Renna Rodrigues, Xu Zhao, Yongle Zhang, Pranay U. Jain, and Michael Stumm. [Simple Testing Can Prevent Most Critical Failures: An Analysis of Production Failures in Distributed Data-Intensive Systems](https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf). At *11th USENIX Symposium on Operating Systems Design and Implementation* (OSDI), October 2014.
|
||||
[^39]: Casey Rosenthal and Nora Jones. [*Chaos Engineering*](https://learning.oreilly.com/library/view/chaos-engineering/9781492043850/). O'Reilly Media, April 2020. ISBN: 9781492043867
|
||||
[^40]: Eduardo Pinheiro, Wolf-Dietrich Weber, and Luiz Andre Barroso. [Failure Trends in a Large Disk Drive Population](https://www.usenix.org/legacy/events/fast07/tech/full_papers/pinheiro/pinheiro_old.pdf). At *5th USENIX Conference on File and Storage Technologies* (FAST), February 2007.
|
||||
[^41]: Bianca Schroeder and Garth A. Gibson. [Disk failures in the real world: What does an MTTF of 1,000,000 hours mean to you?](https://www.usenix.org/legacy/events/fast07/tech/schroeder/schroeder.pdf) At *5th USENIX Conference on File and Storage Technologies* (FAST), February 2007.
|
||||
[^42]: Andy Klein. [Backblaze Drive Stats for Q2 2021](https://www.backblaze.com/blog/backblaze-drive-stats-for-q2-2021/). *backblaze.com*, August 2021. Archived at [perma.cc/2943-UD5E](https://perma.cc/2943-UD5E)
|
||||
[^43]: Iyswarya Narayanan, Di Wang, Myeongjae Jeon, Bikash Sharma, Laura Caulfield, Anand Sivasubramaniam, Ben Cutler, Jie Liu, Badriddine Khessib, and Kushagra Vaid. [SSD Failures in Datacenters: What? When? and Why?](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/08/a7-narayanan.pdf) At *9th ACM International on Systems and Storage Conference* (SYSTOR), June 2016. [doi:10.1145/2928275.2928278](https://doi.org/10.1145/2928275.2928278)
|
||||
[^44]: Alibaba Cloud Storage Team. [Storage System Design Analysis: Factors Affecting NVMe SSD Performance (1)](https://www.alibabacloud.com/blog/594375). *alibabacloud.com*, January 2019. Archived at [archive.org](https://web.archive.org/web/20230522005034/https%3A//www.alibabacloud.com/blog/594375)
|
||||
[^45]: Bianca Schroeder, Raghav Lagisetty, and Arif Merchant. [Flash Reliability in Production: The Expected and the Unexpected](https://www.usenix.org/system/files/conference/fast16/fast16-papers-schroeder.pdf). At *14th USENIX Conference on File and Storage Technologies* (FAST), February 2016.
|
||||
[^46]: Jacob Alter, Ji Xue, Alma Dimnaku, and Evgenia Smirni. [SSD failures in the field: symptoms, causes, and prediction models](https://dl.acm.org/doi/pdf/10.1145/3295500.3356172). At *International Conference for High Performance Computing, Networking, Storage and Analysis* (SC), November 2019. [doi:10.1145/3295500.3356172](https://doi.org/10.1145/3295500.3356172)
|
||||
[^47]: Daniel Ford, François Labelle, Florentina I. Popovici, Murray Stokely, Van-Anh Truong, Luiz Barroso, Carrie Grimes, and Sean Quinlan. [Availability in Globally Distributed Storage Systems](https://www.usenix.org/legacy/event/osdi10/tech/full_papers/Ford.pdf). At *9th USENIX Symposium on Operating Systems Design and Implementation* (OSDI), October 2010.
|
||||
[^48]: Kashi Venkatesh Vishwanath and Nachiappan Nagappan. [Characterizing Cloud Computing Hardware Reliability](https://www.microsoft.com/en-us/research/wp-content/uploads/2010/06/socc088-vishwanath.pdf). At *1st ACM Symposium on Cloud Computing* (SoCC), June 2010. [doi:10.1145/1807128.1807161](https://doi.org/10.1145/1807128.1807161)
|
||||
[^49]: Peter H. Hochschild, Paul Turner, Jeffrey C. Mogul, Rama Govindaraju, Parthasarathy Ranganathan, David E. Culler, and Amin Vahdat. [Cores that don't count](https://sigops.org/s/conferences/hotos/2021/papers/hotos21-s01-hochschild.pdf). At *Workshop on Hot Topics in Operating Systems* (HotOS), June 2021. [doi:10.1145/3458336.3465297](https://doi.org/10.1145/3458336.3465297)
|
||||
[^50]: Harish Dattatraya Dixit, Sneha Pendharkar, Matt Beadon, Chris Mason, Tejasvi Chakravarthy, Bharath Muthiah, and Sriram Sankar. [Silent Data Corruptions at Scale](https://arxiv.org/abs/2102.11245). *arXiv:2102.11245*, February 2021.
|
||||
[^51]: Diogo Behrens, Marco Serafini, Sergei Arnautov, Flavio P. Junqueira, and Christof Fetzer. [Scalable Error Isolation for Distributed Systems](https://www.usenix.org/conference/nsdi15/technical-sessions/presentation/behrens). At *12th USENIX Symposium on Networked Systems Design and Implementation* (NSDI), May 2015.
|
||||
[^52]: Bianca Schroeder, Eduardo Pinheiro, and Wolf-Dietrich Weber. [DRAM Errors in the Wild: A Large-Scale Field Study](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/35162.pdf). At *11th International Joint Conference on Measurement and Modeling of Computer Systems* (SIGMETRICS), June 2009. [doi:10.1145/1555349.1555372](https://doi.org/10.1145/1555349.1555372)
|
||||
[^53]: Yoongu Kim, Ross Daly, Jeremie Kim, Chris Fallin, Ji Hye Lee, Donghyuk Lee, Chris Wilkerson, Konrad Lai, and Onur Mutlu. [Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors](https://users.ece.cmu.edu/~yoonguk/papers/kim-isca14.pdf). At *41st Annual International Symposium on Computer Architecture* (ISCA), June 2014. [doi:10.5555/2665671.2665726](https://doi.org/10.5555/2665671.2665726)
|
||||
[^54]: Tim Bray. [Worst Case](https://www.tbray.org/ongoing/When/202x/2021/10/08/The-WOrst-Case). *tbray.org*, October 2021. Archived at [perma.cc/4QQM-RTHN](https://perma.cc/4QQM-RTHN)
|
||||
[^55]: Sangeetha Abdu Jyothi. [Solar Superstorms: Planning for an Internet Apocalypse](https://ics.uci.edu/~sabdujyo/papers/sigcomm21-cme.pdf). At *ACM SIGCOMM Conferene*, August 2021. [doi:10.1145/3452296.3472916](https://doi.org/10.1145/3452296.3472916)
|
||||
[^56]: Adrian Cockcroft. [Failure Modes and Continuous Resilience](https://adrianco.medium.com/failure-modes-and-continuous-resilience-6553078caad5). *adrianco.medium.com*, November 2019. Archived at [perma.cc/7SYS-BVJP](https://perma.cc/7SYS-BVJP)
|
||||
[^57]: Shujie Han, Patrick P. C. Lee, Fan Xu, Yi Liu, Cheng He, and Jiongzhou Liu. [An In-Depth Study of Correlated Failures in Production SSD-Based Data Centers](https://www.usenix.org/conference/fast21/presentation/han). At *19th USENIX Conference on File and Storage Technologies* (FAST), February 2021.
|
||||
[^58]: Edmund B. Nightingale, John R. Douceur, and Vince Orgovan. [Cycles, Cells and Platters: An Empirical Analysis of Hardware Failures on a Million Consumer PCs](https://eurosys2011.cs.uni-salzburg.at/pdf/eurosys2011-nightingale.pdf). At *6th European Conference on Computer Systems* (EuroSys), April 2011. [doi:10.1145/1966445.1966477](https://doi.org/10.1145/1966445.1966477)
|
||||
[^59]: Haryadi S. Gunawi, Mingzhe Hao, Tanakorn Leesatapornwongsa, Tiratat Patana-anake, Thanh Do, Jeffry Adityatama, Kurnia J. Eliazar, Agung Laksono, Jeffrey F. Lukman, Vincentius Martin, and Anang D. Satria. [What Bugs Live in the Cloud?](https://ucare.cs.uchicago.edu/pdf/socc14-cbs.pdf) At *5th ACM Symposium on Cloud Computing* (SoCC), November 2014. [doi:10.1145/2670979.2670986](https://doi.org/10.1145/2670979.2670986)
|
||||
[^60]: Jay Kreps. [Getting Real About Distributed System Reliability](https://blog.empathybox.com/post/19574936361/getting-real-about-distributed-system-reliability). *blog.empathybox.com*, March 2012. Archived at [perma.cc/9B5Q-AEBW](https://perma.cc/9B5Q-AEBW)
|
||||
[^61]: Nelson Minar. [Leap Second Crashes Half the Internet](https://www.somebits.com/weblog/tech/bad/leap-second-2012.html). *somebits.com*, July 2012. Archived at [perma.cc/2WB8-D6EU](https://perma.cc/2WB8-D6EU)
|
||||
[^62]: Hewlett Packard Enterprise. [Support Alerts – Customer Bulletin a00092491en\_us](https://support.hpe.com/hpesc/public/docDisplay?docId=emr_na-a00092491en_us). *support.hpe.com*, November 2019. Archived at [perma.cc/S5F6-7ZAC](https://perma.cc/S5F6-7ZAC)
|
||||
[^63]: Lorin Hochstein. [awesome limits](https://github.com/lorin/awesome-limits). *github.com*, November 2020. Archived at [perma.cc/3R5M-E5Q4](https://perma.cc/3R5M-E5Q4)
|
||||
[^64]: Caitie McCaffrey. [Clients Are Jerks: AKA How Halo 4 DoSed the Services at Launch & How We Survived](https://www.caitiem.com/2015/06/23/clients-are-jerks-aka-how-halo-4-dosed-the-services-at-launch-how-we-survived/). *caitiem.com*, June 2015. Archived at [perma.cc/MXX4-W373](https://perma.cc/MXX4-W373)
|
||||
[^65]: Lilia Tang, Chaitanya Bhandari, Yongle Zhang, Anna Karanika, Shuyang Ji, Indranil Gupta, and Tianyin Xu. [Fail through the Cracks: Cross-System Interaction Failures in Modern Cloud Systems](https://tianyin.github.io/pub/csi-failures.pdf). At *18th European Conference on Computer Systems* (EuroSys), May 2023. [doi:10.1145/3552326.3587448](https://doi.org/10.1145/3552326.3587448)
|
||||
[^66]: Mike Ulrich. [Addressing Cascading Failures](https://sre.google/sre-book/addressing-cascading-failures/). In Betsy Beyer, Jennifer Petoff, Chris Jones, and Niall Richard Murphy (ed). [*Site Reliability Engineering: How Google Runs Production Systems*](https://www.oreilly.com/library/view/site-reliability-engineering/9781491929117/). O'Reilly Media, 2016. ISBN: 9781491929124
|
||||
[^67]: Harri Faßbender. [Cascading failures in large-scale distributed systems](https://blog.mi.hdm-stuttgart.de/index.php/2022/03/03/cascading-failures-in-large-scale-distributed-systems/). *blog.mi.hdm-stuttgart.de*, March 2022. Archived at [perma.cc/K7VY-YJRX](https://perma.cc/K7VY-YJRX)
|
||||
[^68]: Richard I. Cook. [How Complex Systems Fail](https://www.adaptivecapacitylabs.com/HowComplexSystemsFail.pdf). Cognitive Technologies Laboratory, April 2000. Archived at [perma.cc/RDS6-2YVA](https://perma.cc/RDS6-2YVA)
|
||||
[^69]: David D. Woods. [STELLA: Report from the SNAFUcatchers Workshop on Coping With Complexity](https://snafucatchers.github.io/). *snafucatchers.github.io*, March 2017. Archived at [archive.org](https://web.archive.org/web/20230306130131/https%3A//snafucatchers.github.io/)
|
||||
[^70]: David Oppenheimer, Archana Ganapathi, and David A. Patterson. [Why Do Internet Services Fail, and What Can Be Done About It?](https://static.usenix.org/events/usits03/tech/full_papers/oppenheimer/oppenheimer.pdf) At *4th USENIX Symposium on Internet Technologies and Systems* (USITS), March 2003.
|
||||
[^71]: Sidney Dekker. [*The Field Guide to Understanding 'Human Error', 3rd Edition*](https://learning.oreilly.com/library/view/the-field-guide/9781317031833/). CRC Press, November 2017. ISBN: 9781472439055
|
||||
[^72]: Sidney Dekker. [*Drift into Failure: From Hunting Broken Components to Understanding Complex Systems*](https://www.taylorfrancis.com/books/mono/10.1201/9781315257396/drift-failure-sidney-dekker). CRC Press, 2011. ISBN: 9781315257396
|
||||
[^73]: John Allspaw. [Blameless PostMortems and a Just Culture](https://www.etsy.com/codeascraft/blameless-postmortems/). *etsy.com*, May 2012. Archived at [perma.cc/YMJ7-NTAP](https://perma.cc/YMJ7-NTAP)
|
||||
[^74]: Itzy Sabo. [Uptime Guarantees — A Pragmatic Perspective](https://world.hey.com/itzy/uptime-guarantees-a-pragmatic-perspective-736d7ea4). *world.hey.com*, March 2023. Archived at [perma.cc/F7TU-78JB](https://perma.cc/F7TU-78JB)
|
||||
[^75]: Michael Jurewitz. [The Human Impact of Bugs](http://jury.me/blog/2013/3/14/the-human-impact-of-bugs). *jury.me*, March 2013. Archived at [perma.cc/5KQ4-VDYL](https://perma.cc/5KQ4-VDYL)
|
||||
[^76]: Mark Halper. [How Software Bugs led to 'One of the Greatest Miscarriages of Justice' in British History](https://cacm.acm.org/news/how-software-bugs-led-to-one-of-the-greatest-miscarriages-of-justice-in-british-history/). *Communications of the ACM*, January 2025. [doi:10.1145/3703779](https://doi.org/10.1145/3703779)
|
||||
[^77]: Nicholas Bohm, James Christie, Peter Bernard Ladkin, Bev Littlewood, Paul Marshall, Stephen Mason, Martin Newby, Steven J. Murdoch, Harold Thimbleby, and Martyn Thomas. [The legal rule that computers are presumed to be operating correctly – unforeseen and unjust consequences](https://www.benthamsgaze.org/wp-content/uploads/2022/06/briefing-presumption-that-computers-are-reliable.pdf). Briefing note, *benthamsgaze.org*, June 2022. Archived at [perma.cc/WQ6X-TMW4](https://perma.cc/WQ6X-TMW4)
|
||||
[^78]: Dan McKinley. [Choose Boring Technology](https://mcfunley.com/choose-boring-technology). *mcfunley.com*, March 2015. Archived at [perma.cc/7QW7-J4YP](https://perma.cc/7QW7-J4YP)
|
||||
[^79]: Andy Warfield. [Building and operating a pretty big storage system called S3](https://www.allthingsdistributed.com/2023/07/building-and-operating-a-pretty-big-storage-system.html). *allthingsdistributed.com*, July 2023. Archived at [perma.cc/7LPK-TP7V](https://perma.cc/7LPK-TP7V)
|
||||
[^80]: Marc Brooker. [Surprising Scalability of Multitenancy](https://brooker.co.za/blog/2023/03/23/economics.html). *brooker.co.za*, March 2023. Archived at [perma.cc/ZZD9-VV8T](https://perma.cc/ZZD9-VV8T)
|
||||
[^81]: Ben Stopford. [Shared Nothing vs. Shared Disk Architectures: An Independent View](http://www.benstopford.com/2009/11/24/understanding-the-shared-nothing-architecture/). *benstopford.com*, November 2009. Archived at [perma.cc/7BXH-EDUR](https://perma.cc/7BXH-EDUR)
|
||||
[^82]: Michael Stonebraker. [The Case for Shared Nothing](https://dsf.berkeley.edu/papers/hpts85-nothing.pdf). *IEEE Database Engineering Bulletin*, volume 9, issue 1, pages 4–9, March 1986.
|
||||
[^83]: Panagiotis Antonopoulos, Alex Budovski, Cristian Diaconu, Alejandro Hernandez Saenz, Jack Hu, Hanuma Kodavalla, Donald Kossmann, Sandeep Lingam, Umar Farooq Minhas, Naveen Prakash, Vijendra Purohit, Hugh Qu, Chaitanya Sreenivas Ravella, Krystyna Reisteter, Sheetal Shrotri, Dixin Tang, and Vikram Wakade. [Socrates: The New SQL Server in the Cloud](https://www.microsoft.com/en-us/research/uploads/prod/2019/05/socrates.pdf). At *ACM International Conference on Management of Data* (SIGMOD), pages 1743–1756, June 2019. [doi:10.1145/3299869.3314047](https://doi.org/10.1145/3299869.3314047)
|
||||
[^84]: Sam Newman. [*Building Microservices*, second edition](https://www.oreilly.com/library/view/building-microservices-2nd/9781492034018/). O'Reilly Media, 2021. ISBN: 9781492034025
|
||||
[^85]: Nathan Ensmenger. [When Good Software Goes Bad: The Surprising Durability of an Ephemeral Technology](https://themaintainers.wpengine.com/wp-content/uploads/2021/04/ensmenger-maintainers-v2.pdf). At *The Maintainers Conference*, April 2016. Archived at [perma.cc/ZXT4-HGZB](https://perma.cc/ZXT4-HGZB)
|
||||
[^86]: Robert L. Glass. [*Facts and Fallacies of Software Engineering*](https://learning.oreilly.com/library/view/facts-and-fallacies/0321117425/). Addison-Wesley Professional, October 2002. ISBN: 9780321117427
|
||||
[^87]: Marianne Bellotti. [*Kill It with Fire*](https://learning.oreilly.com/library/view/kill-it-with/9781098128883/). No Starch Press, April 2021. ISBN: 9781718501188
|
||||
[^88]: Lisanne Bainbridge. [Ironies of automation](https://www.adaptivecapacitylabs.com/IroniesOfAutomation-Bainbridge83.pdf). *Automatica*, volume 19, issue 6, pages 775–779, November 1983. [doi:10.1016/0005-1098(83)90046-8](https://doi.org/10.1016/0005-1098%2883%2990046-8)
|
||||
[^89]: James Hamilton. [On Designing and Deploying Internet-Scale Services](https://www.usenix.org/legacy/events/lisa07/tech/full_papers/hamilton/hamilton.pdf). At *21st Large Installation System Administration Conference* (LISA), November 2007.
|
||||
[^90]: Dotan Horovits. [Open Source for Better Observability](https://horovits.medium.com/open-source-for-better-observability-8c65b5630561). *horovits.medium.com*, October 2021. Archived at [perma.cc/R2HD-U2ZT](https://perma.cc/R2HD-U2ZT)
|
||||
[^91]: Brian Foote and Joseph Yoder. [Big Ball of Mud](http://www.laputan.org/pub/foote/mud.pdf). At *4th Conference on Pattern Languages of Programs* (PLoP), September 1997. Archived at [perma.cc/4GUP-2PBV](https://perma.cc/4GUP-2PBV)
|
||||
[^92]: Marc Brooker. [What is a simple system?](https://brooker.co.za/blog/2022/05/03/simplicity.html) *brooker.co.za*, May 2022. Archived at [perma.cc/U72T-BFVE](https://perma.cc/U72T-BFVE)
|
||||
[^93]: Frederick P. Brooks. [No Silver Bullet – Essence and Accident in Software Engineering](https://worrydream.com/refs/Brooks_1986_-_No_Silver_Bullet.pdf). In [*The Mythical Man-Month*](https://www.oreilly.com/library/view/mythical-man-month-the/0201835959/), Anniversary edition, Addison-Wesley, 1995. ISBN: 9780201835953
|
||||
[^94]: Dan Luu. [Against essential and accidental complexity](https://danluu.com/essential-complexity/). *danluu.com*, December 2020. Archived at [perma.cc/H5ES-69KC](https://perma.cc/H5ES-69KC)
|
||||
[^95]: Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. [*Design Patterns: Elements of Reusable Object-Oriented Software*](https://learning.oreilly.com/library/view/design-patterns-elements/0201633612/). Addison-Wesley Professional, October 1994. ISBN: 9780201633610
|
||||
[^96]: Eric Evans. [*Domain-Driven Design: Tackling Complexity in the Heart of Software*](https://learning.oreilly.com/library/view/domain-driven-design-tackling/0321125215/). Addison-Wesley Professional, August 2003. ISBN: 9780321125217
|
||||
[^97]: Hongyu Pei Breivold, Ivica Crnkovic, and Peter J. Eriksson. [Analyzing Software Evolvability](https://www.es.mdh.se/pdf_publications/1251.pdf). at *32nd Annual IEEE International Computer Software and Applications Conference* (COMPSAC), July 2008. [doi:10.1109/COMPSAC.2008.50](https://doi.org/10.1109/COMPSAC.2008.50)
|
||||
[^98]: Enrico Zaninotto. [From X programming to the X organisation](https://martinfowler.com/articles/zaninotto.pdf). At *XP Conference*, May 2002. Archived at [perma.cc/R9AR-QCKZ](https://perma.cc/R9AR-QCKZ)
|
||||
[^1]: Mike Cvet. [How We Learned to Stop Worrying and Love Fan-In at Twitter](https://www.youtube.com/watch?v=WEgCjwyXvwc). At *QCon San Francisco*, December 2016.
|
||||
[^2]: Raffi Krikorian. [Timelines at Scale](https://www.infoq.com/presentations/Twitter-Timeline-Scalability/). At *QCon San Francisco*, November 2012. Archived at [perma.cc/V9G5-KLYK](https://perma.cc/V9G5-KLYK)
|
||||
[^3]: Twitter. [Twitter’s Recommendation Algorithm](https://blog.twitter.com/engineering/en_us/topics/open-source/2023/twitter-recommendation-algorithm). *blog.twitter.com*, March 2023. Archived at [perma.cc/L5GT-229T](https://perma.cc/L5GT-229T)
|
||||
[^4]: Raffi Krikorian. [New Tweets per second record, and how!](https://blog.twitter.com/engineering/en_us/a/2013/new-tweets-per-second-record-and-how) *blog.twitter.com*, August 2013. Archived at [perma.cc/6JZN-XJYN](https://perma.cc/6JZN-XJYN)
|
||||
[^5]: Jaz Volpert. [When Imperfect Systems are Good, Actually: Bluesky’s Lossy Timelines](https://jazco.dev/2025/02/19/imperfection/). *jazco.dev*, February 2025. Archived at [perma.cc/2PVE-L2MX](https://perma.cc/2PVE-L2MX)
|
||||
[^6]: Samuel Axon. [3% of Twitter’s Servers Dedicated to Justin Bieber](https://mashable.com/archive/justin-bieber-twitter). *mashable.com*, September 2010. Archived at [perma.cc/F35N-CGVX](https://perma.cc/F35N-CGVX)
|
||||
[^7]: Nathan Bronson, Abutalib Aghayev, Aleksey Charapko, and Timothy Zhu. [Metastable Failures in Distributed Systems](https://sigops.org/s/conferences/hotos/2021/papers/hotos21-s11-bronson.pdf). At *Workshop on Hot Topics in Operating Systems* (HotOS), May 2021. [doi:10.1145/3458336.3465286](https://doi.org/10.1145/3458336.3465286)
|
||||
[^8]: Marc Brooker. [Metastability and Distributed Systems](https://brooker.co.za/blog/2021/05/24/metastable.html). *brooker.co.za*, May 2021. Archived at [perma.cc/7FGJ-7XRK](https://perma.cc/7FGJ-7XRK)
|
||||
[^9]: Marc Brooker. [Exponential Backoff And Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/). *aws.amazon.com*, March 2015. Archived at [perma.cc/R6MS-AZKH](https://perma.cc/R6MS-AZKH)
|
||||
[^10]: Marc Brooker. [What is Backoff For?](https://brooker.co.za/blog/2022/08/11/backoff.html) *brooker.co.za*, August 2022. Archived at [perma.cc/PW9N-55Q5](https://perma.cc/PW9N-55Q5)
|
||||
[^11]: Michael T. Nygard. [*Release It!*](https://learning.oreilly.com/library/view/release-it-2nd/9781680504552/), 2nd Edition. Pragmatic Bookshelf, January 2018. ISBN: 9781680502398
|
||||
[^12]: Frank Chen. [Slowing Down to Speed Up – Circuit Breakers for Slack’s CI/CD](https://slack.engineering/circuit-breakers/). *slack.engineering*, August 2022. Archived at [perma.cc/5FGS-ZPH3](https://perma.cc/5FGS-ZPH3)
|
||||
[^13]: Marc Brooker. [Fixing retries with token buckets and circuit breakers](https://brooker.co.za/blog/2022/02/28/retries.html). *brooker.co.za*, February 2022. Archived at [perma.cc/MD6N-GW26](https://perma.cc/MD6N-GW26)
|
||||
[^14]: David Yanacek. [Using load shedding to avoid overload](https://aws.amazon.com/builders-library/using-load-shedding-to-avoid-overload/). Amazon Builders’ Library, *aws.amazon.com*. Archived at [perma.cc/9SAW-68MP](https://perma.cc/9SAW-68MP)
|
||||
[^15]: Matthew Sackman. [Pushing Back](https://wellquite.org/posts/lshift/pushing_back/). *wellquite.org*, May 2016. Archived at [perma.cc/3KCZ-RUFY](https://perma.cc/3KCZ-RUFY)
|
||||
[^16]: Dmitry Kopytkov and Patrick Lee. [Meet Bandaid, the Dropbox service proxy](https://dropbox.tech/infrastructure/meet-bandaid-the-dropbox-service-proxy). *dropbox.tech*, March 2018. Archived at [perma.cc/KUU6-YG4S](https://perma.cc/KUU6-YG4S)
|
||||
[^17]: Haryadi S. Gunawi, Riza O. Suminto, Russell Sears, Casey Golliher, Swaminathan Sundararaman, Xing Lin, Tim Emami, Weiguang Sheng, Nematollah Bidokhti, Caitie McCaffrey, Gary Grider, Parks M. Fields, Kevin Harms, Robert B. Ross, Andree Jacobson, Robert Ricci, Kirk Webb, Peter Alvaro, H. Birali Runesha, Mingzhe Hao, and Huaicheng Li. [Fail-Slow at Scale: Evidence of Hardware Performance Faults in Large Production Systems](https://www.usenix.org/system/files/conference/fast18/fast18-gunawi.pdf). At *16th USENIX Conference on File and Storage Technologies*, February 2018.
|
||||
[^18]: Marc Brooker. [Is the Mean Really Useless?](https://brooker.co.za/blog/2017/12/28/mean.html) *brooker.co.za*, December 2017. Archived at [perma.cc/U5AE-CVEM](https://perma.cc/U5AE-CVEM)
|
||||
[^19]: Giuseppe DeCandia, Deniz Hastorun, Madan Jampani, Gunavardhan Kakulapati, Avinash Lakshman, Alex Pilchin, Swaminathan Sivasubramanian, Peter Vosshall, and Werner Vogels. [Dynamo: Amazon’s Highly Available Key-Value Store](https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf). At *21st ACM Symposium on Operating Systems Principles* (SOSP), October 2007. [doi:10.1145/1294261.1294281](https://doi.org/10.1145/1294261.1294281)
|
||||
[^20]: Kathryn Whitenton. [The Need for Speed, 23 Years Later](https://www.nngroup.com/articles/the-need-for-speed/). *nngroup.com*, May 2020. Archived at [perma.cc/C4ER-LZYA](https://perma.cc/C4ER-LZYA)
|
||||
[^21]: Greg Linden. [Marissa Mayer at Web 2.0](https://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html). *glinden.blogspot.com*, November 2005. Archived at [perma.cc/V7EA-3VXB](https://perma.cc/V7EA-3VXB)
|
||||
[^22]: Jake Brutlag. [Speed Matters for Google Web Search](https://services.google.com/fh/files/blogs/google_delayexp.pdf). *services.google.com*, June 2009. Archived at [perma.cc/BK7R-X7M2](https://perma.cc/BK7R-X7M2)
|
||||
[^23]: Eric Schurman and Jake Brutlag. [Performance Related Changes and their User Impact](https://www.youtube.com/watch?v=bQSE51-gr2s). Talk at *Velocity 2009*.
|
||||
[^24]: Akamai Technologies, Inc. [The State of Online Retail Performance](https://web.archive.org/web/20210729180749/https%3A//www.akamai.com/us/en/multimedia/documents/report/akamai-state-of-online-retail-performance-spring-2017.pdf). *akamai.com*, April 2017. Archived at [perma.cc/UEK2-HYCS](https://perma.cc/UEK2-HYCS)
|
||||
[^25]: Xiao Bai, Ioannis Arapakis, B. Barla Cambazoglu, and Ana Freire. [Understanding and Leveraging the Impact of Response Latency on User Behaviour in Web Search](https://iarapakis.github.io/papers/TOIS17.pdf). *ACM Transactions on Information Systems*, volume 36, issue 2, article 21, April 2018. [doi:10.1145/3106372](https://doi.org/10.1145/3106372)
|
||||
[^26]: Jeffrey Dean and Luiz André Barroso. [The Tail at Scale](https://cacm.acm.org/research/the-tail-at-scale/). *Communications of the ACM*, volume 56, issue 2, pages 74–80, February 2013. [doi:10.1145/2408776.2408794](https://doi.org/10.1145/2408776.2408794)
|
||||
[^27]: Alex Hidalgo. [*Implementing Service Level Objectives: A Practical Guide to SLIs, SLOs, and Error Budgets*](https://www.oreilly.com/library/view/implementing-service-level/9781492076803/). O’Reilly Media, September 2020. ISBN: 1492076813
|
||||
[^28]: Jeffrey C. Mogul and John Wilkes. [Nines are Not Enough: Meaningful Metrics for Clouds](https://research.google/pubs/pub48033/). At *17th Workshop on Hot Topics in Operating Systems* (HotOS), May 2019. [doi:10.1145/3317550.3321432](https://doi.org/10.1145/3317550.3321432)
|
||||
[^29]: Tamás Hauer, Philipp Hoffmann, John Lunney, Dan Ardelean, and Amer Diwan. [Meaningful Availability](https://www.usenix.org/conference/nsdi20/presentation/hauer). At *17th USENIX Symposium on Networked Systems Design and Implementation* (NSDI), February 2020.
|
||||
[^30]: Ted Dunning. [The t-digest: Efficient estimates of distributions](https://www.sciencedirect.com/science/article/pii/S2665963820300403). *Software Impacts*, volume 7, article 100049, February 2021. [doi:10.1016/j.simpa.2020.100049](https://doi.org/10.1016/j.simpa.2020.100049)
|
||||
[^31]: David Kohn. [How percentile approximation works (and why it’s more useful than averages)](https://www.timescale.com/blog/how-percentile-approximation-works-and-why-its-more-useful-than-averages/). *timescale.com*, September 2021. Archived at [perma.cc/3PDP-NR8B](https://perma.cc/3PDP-NR8B)
|
||||
[^32]: Heinrich Hartmann and Theo Schlossnagle. [Circllhist — A Log-Linear Histogram Data Structure for IT Infrastructure Monitoring](https://arxiv.org/pdf/2001.06561.pdf). *arxiv.org*, January 2020.
|
||||
[^33]: Charles Masson, Jee E. Rim, and Homin K. Lee. [DDSketch: A Fast and Fully-Mergeable Quantile Sketch with Relative-Error Guarantees](https://www.vldb.org/pvldb/vol12/p2195-masson.pdf). *Proceedings of the VLDB Endowment*, volume 12, issue 12, pages 2195–2205, August 2019. [doi:10.14778/3352063.3352135](https://doi.org/10.14778/3352063.3352135)
|
||||
[^34]: Baron Schwartz. [Why Percentiles Don’t Work the Way You Think](https://orangematter.solarwinds.com/2016/11/18/why-percentiles-dont-work-the-way-you-think/). *solarwinds.com*, November 2016. Archived at [perma.cc/469T-6UGB](https://perma.cc/469T-6UGB)
|
||||
[^35]: Walter L. Heimerdinger and Charles B. Weinstock. [A Conceptual Framework for System Fault Tolerance](https://resources.sei.cmu.edu/asset_files/TechnicalReport/1992_005_001_16112.pdf). Technical Report CMU/SEI-92-TR-033, Software Engineering Institute, Carnegie Mellon University, October 1992. Archived at [perma.cc/GD2V-DMJW](https://perma.cc/GD2V-DMJW)
|
||||
[^36]: Felix C. Gärtner. [Fundamentals of fault-tolerant distributed computing in asynchronous environments](https://dl.acm.org/doi/pdf/10.1145/311531.311532). *ACM Computing Surveys*, volume 31, issue 1, pages 1–26, March 1999. [doi:10.1145/311531.311532](https://doi.org/10.1145/311531.311532)
|
||||
[^37]: Algirdas Avižienis, Jean-Claude Laprie, Brian Randell, and Carl Landwehr. [Basic Concepts and Taxonomy of Dependable and Secure Computing](https://hdl.handle.net/1903/6459). *IEEE Transactions on Dependable and Secure Computing*, volume 1, issue 1, January 2004. [doi:10.1109/TDSC.2004.2](https://doi.org/10.1109/TDSC.2004.2)
|
||||
[^38]: Ding Yuan, Yu Luo, Xin Zhuang, Guilherme Renna Rodrigues, Xu Zhao, Yongle Zhang, Pranay U. Jain, and Michael Stumm. [Simple Testing Can Prevent Most Critical Failures: An Analysis of Production Failures in Distributed Data-Intensive Systems](https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf). At *11th USENIX Symposium on Operating Systems Design and Implementation* (OSDI), October 2014.
|
||||
[^39]: Casey Rosenthal and Nora Jones. [*Chaos Engineering*](https://learning.oreilly.com/library/view/chaos-engineering/9781492043850/). O’Reilly Media, April 2020. ISBN: 9781492043867
|
||||
[^40]: Eduardo Pinheiro, Wolf-Dietrich Weber, and Luiz Andre Barroso. [Failure Trends in a Large Disk Drive Population](https://www.usenix.org/legacy/events/fast07/tech/full_papers/pinheiro/pinheiro_old.pdf). At *5th USENIX Conference on File and Storage Technologies* (FAST), February 2007.
|
||||
[^41]: Bianca Schroeder and Garth A. Gibson. [Disk failures in the real world: What does an MTTF of 1,000,000 hours mean to you?](https://www.usenix.org/legacy/events/fast07/tech/schroeder/schroeder.pdf) At *5th USENIX Conference on File and Storage Technologies* (FAST), February 2007.
|
||||
[^42]: Andy Klein. [Backblaze Drive Stats for Q2 2021](https://www.backblaze.com/blog/backblaze-drive-stats-for-q2-2021/). *backblaze.com*, August 2021. Archived at [perma.cc/2943-UD5E](https://perma.cc/2943-UD5E)
|
||||
[^43]: Iyswarya Narayanan, Di Wang, Myeongjae Jeon, Bikash Sharma, Laura Caulfield, Anand Sivasubramaniam, Ben Cutler, Jie Liu, Badriddine Khessib, and Kushagra Vaid. [SSD Failures in Datacenters: What? When? and Why?](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/08/a7-narayanan.pdf) At *9th ACM International on Systems and Storage Conference* (SYSTOR), June 2016. [doi:10.1145/2928275.2928278](https://doi.org/10.1145/2928275.2928278)
|
||||
[^44]: Alibaba Cloud Storage Team. [Storage System Design Analysis: Factors Affecting NVMe SSD Performance (1)](https://www.alibabacloud.com/blog/594375). *alibabacloud.com*, January 2019. Archived at [archive.org](https://web.archive.org/web/20230522005034/https%3A//www.alibabacloud.com/blog/594375)
|
||||
[^45]: Bianca Schroeder, Raghav Lagisetty, and Arif Merchant. [Flash Reliability in Production: The Expected and the Unexpected](https://www.usenix.org/system/files/conference/fast16/fast16-papers-schroeder.pdf). At *14th USENIX Conference on File and Storage Technologies* (FAST), February 2016.
|
||||
[^46]: Jacob Alter, Ji Xue, Alma Dimnaku, and Evgenia Smirni. [SSD failures in the field: symptoms, causes, and prediction models](https://dl.acm.org/doi/pdf/10.1145/3295500.3356172). At *International Conference for High Performance Computing, Networking, Storage and Analysis* (SC), November 2019. [doi:10.1145/3295500.3356172](https://doi.org/10.1145/3295500.3356172)
|
||||
[^47]: Daniel Ford, François Labelle, Florentina I. Popovici, Murray Stokely, Van-Anh Truong, Luiz Barroso, Carrie Grimes, and Sean Quinlan. [Availability in Globally Distributed Storage Systems](https://www.usenix.org/legacy/event/osdi10/tech/full_papers/Ford.pdf). At *9th USENIX Symposium on Operating Systems Design and Implementation* (OSDI), October 2010.
|
||||
[^48]: Kashi Venkatesh Vishwanath and Nachiappan Nagappan. [Characterizing Cloud Computing Hardware Reliability](https://www.microsoft.com/en-us/research/wp-content/uploads/2010/06/socc088-vishwanath.pdf). At *1st ACM Symposium on Cloud Computing* (SoCC), June 2010. [doi:10.1145/1807128.1807161](https://doi.org/10.1145/1807128.1807161)
|
||||
[^49]: Peter H. Hochschild, Paul Turner, Jeffrey C. Mogul, Rama Govindaraju, Parthasarathy Ranganathan, David E. Culler, and Amin Vahdat. [Cores that don’t count](https://sigops.org/s/conferences/hotos/2021/papers/hotos21-s01-hochschild.pdf). At *Workshop on Hot Topics in Operating Systems* (HotOS), June 2021. [doi:10.1145/3458336.3465297](https://doi.org/10.1145/3458336.3465297)
|
||||
[^50]: Harish Dattatraya Dixit, Sneha Pendharkar, Matt Beadon, Chris Mason, Tejasvi Chakravarthy, Bharath Muthiah, and Sriram Sankar. [Silent Data Corruptions at Scale](https://arxiv.org/abs/2102.11245). *arXiv:2102.11245*, February 2021.
|
||||
[^51]: Diogo Behrens, Marco Serafini, Sergei Arnautov, Flavio P. Junqueira, and Christof Fetzer. [Scalable Error Isolation for Distributed Systems](https://www.usenix.org/conference/nsdi15/technical-sessions/presentation/behrens). At *12th USENIX Symposium on Networked Systems Design and Implementation* (NSDI), May 2015.
|
||||
[^52]: Bianca Schroeder, Eduardo Pinheiro, and Wolf-Dietrich Weber. [DRAM Errors in the Wild: A Large-Scale Field Study](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/35162.pdf). At *11th International Joint Conference on Measurement and Modeling of Computer Systems* (SIGMETRICS), June 2009. [doi:10.1145/1555349.1555372](https://doi.org/10.1145/1555349.1555372)
|
||||
[^53]: Yoongu Kim, Ross Daly, Jeremie Kim, Chris Fallin, Ji Hye Lee, Donghyuk Lee, Chris Wilkerson, Konrad Lai, and Onur Mutlu. [Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors](https://users.ece.cmu.edu/~yoonguk/papers/kim-isca14.pdf). At *41st Annual International Symposium on Computer Architecture* (ISCA), June 2014. [doi:10.5555/2665671.2665726](https://doi.org/10.5555/2665671.2665726)
|
||||
[^54]: Tim Bray. [Worst Case](https://www.tbray.org/ongoing/When/202x/2021/10/08/The-WOrst-Case). *tbray.org*, October 2021. Archived at [perma.cc/4QQM-RTHN](https://perma.cc/4QQM-RTHN)
|
||||
[^55]: Sangeetha Abdu Jyothi. [Solar Superstorms: Planning for an Internet Apocalypse](https://ics.uci.edu/~sabdujyo/papers/sigcomm21-cme.pdf). At *ACM SIGCOMM Conferene*, August 2021. [doi:10.1145/3452296.3472916](https://doi.org/10.1145/3452296.3472916)
|
||||
[^56]: Adrian Cockcroft. [Failure Modes and Continuous Resilience](https://adrianco.medium.com/failure-modes-and-continuous-resilience-6553078caad5). *adrianco.medium.com*, November 2019. Archived at [perma.cc/7SYS-BVJP](https://perma.cc/7SYS-BVJP)
|
||||
[^57]: Shujie Han, Patrick P. C. Lee, Fan Xu, Yi Liu, Cheng He, and Jiongzhou Liu. [An In-Depth Study of Correlated Failures in Production SSD-Based Data Centers](https://www.usenix.org/conference/fast21/presentation/han). At *19th USENIX Conference on File and Storage Technologies* (FAST), February 2021.
|
||||
[^58]: Edmund B. Nightingale, John R. Douceur, and Vince Orgovan. [Cycles, Cells and Platters: An Empirical Analysis of Hardware Failures on a Million Consumer PCs](https://eurosys2011.cs.uni-salzburg.at/pdf/eurosys2011-nightingale.pdf). At *6th European Conference on Computer Systems* (EuroSys), April 2011. [doi:10.1145/1966445.1966477](https://doi.org/10.1145/1966445.1966477)
|
||||
[^59]: Haryadi S. Gunawi, Mingzhe Hao, Tanakorn Leesatapornwongsa, Tiratat Patana-anake, Thanh Do, Jeffry Adityatama, Kurnia J. Eliazar, Agung Laksono, Jeffrey F. Lukman, Vincentius Martin, and Anang D. Satria. [What Bugs Live in the Cloud?](https://ucare.cs.uchicago.edu/pdf/socc14-cbs.pdf) At *5th ACM Symposium on Cloud Computing* (SoCC), November 2014. [doi:10.1145/2670979.2670986](https://doi.org/10.1145/2670979.2670986)
|
||||
[^60]: Jay Kreps. [Getting Real About Distributed System Reliability](https://blog.empathybox.com/post/19574936361/getting-real-about-distributed-system-reliability). *blog.empathybox.com*, March 2012. Archived at [perma.cc/9B5Q-AEBW](https://perma.cc/9B5Q-AEBW)
|
||||
[^61]: Nelson Minar. [Leap Second Crashes Half the Internet](https://www.somebits.com/weblog/tech/bad/leap-second-2012.html). *somebits.com*, July 2012. Archived at [perma.cc/2WB8-D6EU](https://perma.cc/2WB8-D6EU)
|
||||
[^62]: Hewlett Packard Enterprise. [Support Alerts – Customer Bulletin a00092491en\_us](https://support.hpe.com/hpesc/public/docDisplay?docId=emr_na-a00092491en_us). *support.hpe.com*, November 2019. Archived at [perma.cc/S5F6-7ZAC](https://perma.cc/S5F6-7ZAC)
|
||||
[^63]: Lorin Hochstein. [awesome limits](https://github.com/lorin/awesome-limits). *github.com*, November 2020. Archived at [perma.cc/3R5M-E5Q4](https://perma.cc/3R5M-E5Q4)
|
||||
[^64]: Caitie McCaffrey. [Clients Are Jerks: AKA How Halo 4 DoSed the Services at Launch & How We Survived](https://www.caitiem.com/2015/06/23/clients-are-jerks-aka-how-halo-4-dosed-the-services-at-launch-how-we-survived/). *caitiem.com*, June 2015. Archived at [perma.cc/MXX4-W373](https://perma.cc/MXX4-W373)
|
||||
[^65]: Lilia Tang, Chaitanya Bhandari, Yongle Zhang, Anna Karanika, Shuyang Ji, Indranil Gupta, and Tianyin Xu. [Fail through the Cracks: Cross-System Interaction Failures in Modern Cloud Systems](https://tianyin.github.io/pub/csi-failures.pdf). At *18th European Conference on Computer Systems* (EuroSys), May 2023. [doi:10.1145/3552326.3587448](https://doi.org/10.1145/3552326.3587448)
|
||||
[^66]: Mike Ulrich. [Addressing Cascading Failures](https://sre.google/sre-book/addressing-cascading-failures/). In Betsy Beyer, Jennifer Petoff, Chris Jones, and Niall Richard Murphy (ed). [*Site Reliability Engineering: How Google Runs Production Systems*](https://www.oreilly.com/library/view/site-reliability-engineering/9781491929117/). O’Reilly Media, 2016. ISBN: 9781491929124
|
||||
[^67]: Harri Faßbender. [Cascading failures in large-scale distributed systems](https://blog.mi.hdm-stuttgart.de/index.php/2022/03/03/cascading-failures-in-large-scale-distributed-systems/). *blog.mi.hdm-stuttgart.de*, March 2022. Archived at [perma.cc/K7VY-YJRX](https://perma.cc/K7VY-YJRX)
|
||||
[^68]: Richard I. Cook. [How Complex Systems Fail](https://www.adaptivecapacitylabs.com/HowComplexSystemsFail.pdf). Cognitive Technologies Laboratory, April 2000. Archived at [perma.cc/RDS6-2YVA](https://perma.cc/RDS6-2YVA)
|
||||
[^69]: David D. Woods. [STELLA: Report from the SNAFUcatchers Workshop on Coping With Complexity](https://snafucatchers.github.io/). *snafucatchers.github.io*, March 2017. Archived at [archive.org](https://web.archive.org/web/20230306130131/https%3A//snafucatchers.github.io/)
|
||||
[^70]: David Oppenheimer, Archana Ganapathi, and David A. Patterson. [Why Do Internet Services Fail, and What Can Be Done About It?](https://static.usenix.org/events/usits03/tech/full_papers/oppenheimer/oppenheimer.pdf) At *4th USENIX Symposium on Internet Technologies and Systems* (USITS), March 2003.
|
||||
[^71]: Sidney Dekker. [*The Field Guide to Understanding ‘Human Error’, 3rd Edition*](https://learning.oreilly.com/library/view/the-field-guide/9781317031833/). CRC Press, November 2017. ISBN: 9781472439055
|
||||
[^72]: Sidney Dekker. [*Drift into Failure: From Hunting Broken Components to Understanding Complex Systems*](https://www.taylorfrancis.com/books/mono/10.1201/9781315257396/drift-failure-sidney-dekker). CRC Press, 2011. ISBN: 9781315257396
|
||||
[^73]: John Allspaw. [Blameless PostMortems and a Just Culture](https://www.etsy.com/codeascraft/blameless-postmortems/). *etsy.com*, May 2012. Archived at [perma.cc/YMJ7-NTAP](https://perma.cc/YMJ7-NTAP)
|
||||
[^74]: Itzy Sabo. [Uptime Guarantees — A Pragmatic Perspective](https://world.hey.com/itzy/uptime-guarantees-a-pragmatic-perspective-736d7ea4). *world.hey.com*, March 2023. Archived at [perma.cc/F7TU-78JB](https://perma.cc/F7TU-78JB)
|
||||
[^75]: Michael Jurewitz. [The Human Impact of Bugs](http://jury.me/blog/2013/3/14/the-human-impact-of-bugs). *jury.me*, March 2013. Archived at [perma.cc/5KQ4-VDYL](https://perma.cc/5KQ4-VDYL)
|
||||
[^76]: Mark Halper. [How Software Bugs led to ‘One of the Greatest Miscarriages of Justice’ in British History](https://cacm.acm.org/news/how-software-bugs-led-to-one-of-the-greatest-miscarriages-of-justice-in-british-history/). *Communications of the ACM*, January 2025. [doi:10.1145/3703779](https://doi.org/10.1145/3703779)
|
||||
[^77]: Nicholas Bohm, James Christie, Peter Bernard Ladkin, Bev Littlewood, Paul Marshall, Stephen Mason, Martin Newby, Steven J. Murdoch, Harold Thimbleby, and Martyn Thomas. [The legal rule that computers are presumed to be operating correctly – unforeseen and unjust consequences](https://www.benthamsgaze.org/wp-content/uploads/2022/06/briefing-presumption-that-computers-are-reliable.pdf). Briefing note, *benthamsgaze.org*, June 2022. Archived at [perma.cc/WQ6X-TMW4](https://perma.cc/WQ6X-TMW4)
|
||||
[^78]: Dan McKinley. [Choose Boring Technology](https://mcfunley.com/choose-boring-technology). *mcfunley.com*, March 2015. Archived at [perma.cc/7QW7-J4YP](https://perma.cc/7QW7-J4YP)
|
||||
[^79]: Andy Warfield. [Building and operating a pretty big storage system called S3](https://www.allthingsdistributed.com/2023/07/building-and-operating-a-pretty-big-storage-system.html). *allthingsdistributed.com*, July 2023. Archived at [perma.cc/7LPK-TP7V](https://perma.cc/7LPK-TP7V)
|
||||
[^80]: Marc Brooker. [Surprising Scalability of Multitenancy](https://brooker.co.za/blog/2023/03/23/economics.html). *brooker.co.za*, March 2023. Archived at [perma.cc/ZZD9-VV8T](https://perma.cc/ZZD9-VV8T)
|
||||
[^81]: Ben Stopford. [Shared Nothing vs. Shared Disk Architectures: An Independent View](http://www.benstopford.com/2009/11/24/understanding-the-shared-nothing-architecture/). *benstopford.com*, November 2009. Archived at [perma.cc/7BXH-EDUR](https://perma.cc/7BXH-EDUR)
|
||||
[^82]: Michael Stonebraker. [The Case for Shared Nothing](https://dsf.berkeley.edu/papers/hpts85-nothing.pdf). *IEEE Database Engineering Bulletin*, volume 9, issue 1, pages 4–9, March 1986.
|
||||
[^83]: Panagiotis Antonopoulos, Alex Budovski, Cristian Diaconu, Alejandro Hernandez Saenz, Jack Hu, Hanuma Kodavalla, Donald Kossmann, Sandeep Lingam, Umar Farooq Minhas, Naveen Prakash, Vijendra Purohit, Hugh Qu, Chaitanya Sreenivas Ravella, Krystyna Reisteter, Sheetal Shrotri, Dixin Tang, and Vikram Wakade. [Socrates: The New SQL Server in the Cloud](https://www.microsoft.com/en-us/research/uploads/prod/2019/05/socrates.pdf). At *ACM International Conference on Management of Data* (SIGMOD), pages 1743–1756, June 2019. [doi:10.1145/3299869.3314047](https://doi.org/10.1145/3299869.3314047)
|
||||
[^84]: Sam Newman. [*Building Microservices*, second edition](https://www.oreilly.com/library/view/building-microservices-2nd/9781492034018/). O’Reilly Media, 2021. ISBN: 9781492034025
|
||||
[^85]: Nathan Ensmenger. [When Good Software Goes Bad: The Surprising Durability of an Ephemeral Technology](https://themaintainers.wpengine.com/wp-content/uploads/2021/04/ensmenger-maintainers-v2.pdf). At *The Maintainers Conference*, April 2016. Archived at [perma.cc/ZXT4-HGZB](https://perma.cc/ZXT4-HGZB)
|
||||
[^86]: Robert L. Glass. [*Facts and Fallacies of Software Engineering*](https://learning.oreilly.com/library/view/facts-and-fallacies/0321117425/). Addison-Wesley Professional, October 2002. ISBN: 9780321117427
|
||||
[^87]: Marianne Bellotti. [*Kill It with Fire*](https://learning.oreilly.com/library/view/kill-it-with/9781098128883/). No Starch Press, April 2021. ISBN: 9781718501188
|
||||
[^88]: Lisanne Bainbridge. [Ironies of automation](https://www.adaptivecapacitylabs.com/IroniesOfAutomation-Bainbridge83.pdf). *Automatica*, volume 19, issue 6, pages 775–779, November 1983. [doi:10.1016/0005-1098(83)90046-8](https://doi.org/10.1016/0005-1098%2883%2990046-8)
|
||||
[^89]: James Hamilton. [On Designing and Deploying Internet-Scale Services](https://www.usenix.org/legacy/events/lisa07/tech/full_papers/hamilton/hamilton.pdf). At *21st Large Installation System Administration Conference* (LISA), November 2007.
|
||||
[^90]: Dotan Horovits. [Open Source for Better Observability](https://horovits.medium.com/open-source-for-better-observability-8c65b5630561). *horovits.medium.com*, October 2021. Archived at [perma.cc/R2HD-U2ZT](https://perma.cc/R2HD-U2ZT)
|
||||
[^91]: Brian Foote and Joseph Yoder. [Big Ball of Mud](http://www.laputan.org/pub/foote/mud.pdf). At *4th Conference on Pattern Languages of Programs* (PLoP), September 1997. Archived at [perma.cc/4GUP-2PBV](https://perma.cc/4GUP-2PBV)
|
||||
[^92]: Marc Brooker. [What is a simple system?](https://brooker.co.za/blog/2022/05/03/simplicity.html) *brooker.co.za*, May 2022. Archived at [perma.cc/U72T-BFVE](https://perma.cc/U72T-BFVE)
|
||||
[^93]: Frederick P. Brooks. [No Silver Bullet – Essence and Accident in Software Engineering](https://worrydream.com/refs/Brooks_1986_-_No_Silver_Bullet.pdf). In [*The Mythical Man-Month*](https://www.oreilly.com/library/view/mythical-man-month-the/0201835959/), Anniversary edition, Addison-Wesley, 1995. ISBN: 9780201835953
|
||||
[^94]: Dan Luu. [Against essential and accidental complexity](https://danluu.com/essential-complexity/). *danluu.com*, December 2020. Archived at [perma.cc/H5ES-69KC](https://perma.cc/H5ES-69KC)
|
||||
[^95]: Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. [*Design Patterns: Elements of Reusable Object-Oriented Software*](https://learning.oreilly.com/library/view/design-patterns-elements/0201633612/). Addison-Wesley Professional, October 1994. ISBN: 9780201633610
|
||||
[^96]: Eric Evans. [*Domain-Driven Design: Tackling Complexity in the Heart of Software*](https://learning.oreilly.com/library/view/domain-driven-design-tackling/0321125215/). Addison-Wesley Professional, August 2003. ISBN: 9780321125217
|
||||
[^97]: Hongyu Pei Breivold, Ivica Crnkovic, and Peter J. Eriksson. [Analyzing Software Evolvability](https://www.es.mdh.se/pdf_publications/1251.pdf). at *32nd Annual IEEE International Computer Software and Applications Conference* (COMPSAC), July 2008. [doi:10.1109/COMPSAC.2008.50](https://doi.org/10.1109/COMPSAC.2008.50)
|
||||
[^98]: Enrico Zaninotto. [From X programming to the X organisation](https://martinfowler.com/articles/zaninotto.pdf). At *XP Conference*, May 2002. Archived at [perma.cc/R9AR-QCKZ](https://perma.cc/R9AR-QCKZ)
|
||||
|
@ -4,6 +4,8 @@ weight: 103
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||

|
||||
|
||||
> *语言的边界就是思想的边界。*
|
||||
>
|
||||
> 路德维希·维特根斯坦,《逻辑哲学论》(1922)
|
||||
@ -144,9 +146,9 @@ NoSQL 运动的一个持久影响是 **文档模型** 的普及,它通常将
|
||||
|
||||
```sql
|
||||
SELECT users.*, regions.region_name
|
||||
FROM users
|
||||
JOIN regions ON users.region_id = regions.id
|
||||
WHERE users.id = 251;
|
||||
FROM users
|
||||
JOIN regions ON users.region_id = regions.id
|
||||
WHERE users.id = 251;
|
||||
```
|
||||
|
||||
文档数据库可以存储规范化和反规范化的数据,但它们通常与反规范化相关联——部分是因为 JSON 数据模型使得存储额外的反规范化字段变得容易,部分是因为许多文档数据库对连接的支持较弱,使得规范化不方便。一些文档数据库根本不支持连接,因此你必须在应用程序代码中执行它们——也就是说,你首先获取包含 ID 的文档,然后执行第二个查询以将该 ID 解析为另一个文档。在 MongoDB 中,也可以使用聚合管道中的 `$lookup` 操作符执行连接:
|
||||
@ -186,11 +188,11 @@ db.users.aggregate([
|
||||
|
||||
```sql
|
||||
SELECT posts.id, posts.sender_id
|
||||
FROM posts
|
||||
JOIN follows ON posts.sender_id = follows.followee_id
|
||||
WHERE follows.follower_id = current_user
|
||||
ORDER BY posts.timestamp DESC
|
||||
LIMIT 1000
|
||||
FROM posts
|
||||
JOIN follows ON posts.sender_id = follows.followee_id
|
||||
WHERE follows.follower_id = current_user
|
||||
ORDER BY posts.timestamp DESC
|
||||
LIMIT 1000
|
||||
```
|
||||
|
||||
这意味着每当读取时间线时,服务仍然需要执行两个连接:通过 ID 查找帖子以获取实际的帖子内容(以及喜欢和回复数等统计信息),并通过 ID 查找发送者的个人资料(获取他们的用户名、头像和其他详细信息)。这个通过 ID 查找人类可读信息的过程称为 **水合**(hydrating)ID,它本质上是在应用程序代码中执行的连接 [^11]。
|
||||
@ -284,7 +286,7 @@ LIMIT 1000
|
||||
|
||||
```mongodb-json
|
||||
if (user && user.name && !user.first_name) {
|
||||
// 2023 年 12 月 8 日之前编写的文档没有 first_name
|
||||
// 2023年12月08日之前编写的文档没有 first_name
|
||||
user.first_name = user.name.split(" ")[0];
|
||||
}
|
||||
```
|
||||
@ -968,18 +970,18 @@ query ChatApp {
|
||||
[^19]: Martin Odersky. [The Trouble with Types](https://www.infoq.com/presentations/data-types-issues/). At *Strange Loop*, September 2013. Archived at [perma.cc/85QE-PVEP](https://perma.cc/85QE-PVEP)
|
||||
[^20]: Conrad Irwin. [MongoDB—Confessions of a PostgreSQL Lover](https://speakerdeck.com/conradirwin/mongodb-confessions-of-a-postgresql-lover). At *HTML5DevConf*, October 2013. Archived at [perma.cc/C2J6-3AL5](https://perma.cc/C2J6-3AL5)
|
||||
[^21]: [Percona Toolkit Documentation: pt-online-schema-change](https://docs.percona.com/percona-toolkit/pt-online-schema-change.html). *docs.percona.com*, 2023. Archived at [perma.cc/9K8R-E5UH](https://perma.cc/9K8R-E5UH)
|
||||
[^22]: Shlomi Noach. [gh-ost: GitHub's Online Schema Migration Tool for MySQL](https://github.blog/2016-08-01-gh-ost-github-s-online-migration-tool-for-mysql/). *github.blog*, August 2016. Archived at [perma.cc/7XAG-XB72](https://perma.cc/7XAG-XB72)
|
||||
[^22]: Shlomi Noach. [gh-ost: GitHub’s Online Schema Migration Tool for MySQL](https://github.blog/2016-08-01-gh-ost-github-s-online-migration-tool-for-mysql/). *github.blog*, August 2016. Archived at [perma.cc/7XAG-XB72](https://perma.cc/7XAG-XB72)
|
||||
[^23]: Shayon Mukherjee. [pg-osc: Zero downtime schema changes in PostgreSQL](https://www.shayon.dev/post/2022/47/pg-osc-zero-downtime-schema-changes-in-postgresql/). *shayon.dev*, February 2022. Archived at [perma.cc/35WN-7WMY](https://perma.cc/35WN-7WMY)
|
||||
[^24]: Carlos Pérez-Aradros Herce. [Introducing pgroll: zero-downtime, reversible, schema migrations for Postgres](https://xata.io/blog/pgroll-schema-migrations-postgres). *xata.io*, October 2023. Archived at [archive.org](https://web.archive.org/web/20231008161750/https%3A//xata.io/blog/pgroll-schema-migrations-postgres)
|
||||
[^25]: James C. Corbett, Jeffrey Dean, Michael Epstein, Andrew Fikes, Christopher Frost, JJ Furman, Sanjay Ghemawat, Andrey Gubarev, Christopher Heiser, Peter Hochschild, Wilson Hsieh, Sebastian Kanthak, Eugene Kogan, Hongyi Li, Alexander Lloyd, Sergey Melnik, David Mwaura, David Nagle, Sean Quinlan, Rajesh Rao, Lindsay Rolig, Dale Woodford, Yasushi Saito, Christopher Taylor, Michal Szymaniak, and Ruth Wang. [Spanner: Google's Globally-Distributed Database](https://research.google/pubs/pub39966/). At *10th USENIX Symposium on Operating System Design and Implementation* (OSDI), October 2012.
|
||||
[^25]: James C. Corbett, Jeffrey Dean, Michael Epstein, Andrew Fikes, Christopher Frost, JJ Furman, Sanjay Ghemawat, Andrey Gubarev, Christopher Heiser, Peter Hochschild, Wilson Hsieh, Sebastian Kanthak, Eugene Kogan, Hongyi Li, Alexander Lloyd, Sergey Melnik, David Mwaura, David Nagle, Sean Quinlan, Rajesh Rao, Lindsay Rolig, Dale Woodford, Yasushi Saito, Christopher Taylor, Michal Szymaniak, and Ruth Wang. [Spanner: Google’s Globally-Distributed Database](https://research.google/pubs/pub39966/). At *10th USENIX Symposium on Operating System Design and Implementation* (OSDI), October 2012.
|
||||
[^26]: Donald K. Burleson. [Reduce I/O with Oracle Cluster Tables](http://www.dba-oracle.com/oracle_tip_hash_index_cluster_table.htm). *dba-oracle.com*. Archived at [perma.cc/7LBJ-9X2C](https://perma.cc/7LBJ-9X2C)
|
||||
[^27]: Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C. Hsieh, Deborah A. Wallach, Mike Burrows, Tushar Chandra, Andrew Fikes, and Robert E. Gruber. [Bigtable: A Distributed Storage System for Structured Data](https://research.google/pubs/pub27898/). At *7th USENIX Symposium on Operating System Design and Implementation* (OSDI), November 2006.
|
||||
[^28]: Priscilla Walmsley. [*XQuery, 2nd Edition*](https://learning.oreilly.com/library/view/xquery-2nd-edition/9781491915080/). O'Reilly Media, December 2015. ISBN: 9781491915080
|
||||
[^28]: Priscilla Walmsley. [*XQuery, 2nd Edition*](https://learning.oreilly.com/library/view/xquery-2nd-edition/9781491915080/). O’Reilly Media, December 2015. ISBN: 9781491915080
|
||||
[^29]: Paul C. Bryan, Kris Zyp, and Mark Nottingham. [JavaScript Object Notation (JSON) Pointer](https://www.rfc-editor.org/rfc/rfc6901). RFC 6901, IETF, April 2013.
|
||||
[^30]: Stefan Gössner, Glyn Normington, and Carsten Bormann. [JSONPath: Query Expressions for JSON](https://www.rfc-editor.org/rfc/rfc9535.html). RFC 9535, IETF, February 2024.
|
||||
[^31]: Michael Stonebraker and Andrew Pavlo. [What Goes Around Comes Around… And Around…](https://db.cs.cmu.edu/papers/2024/whatgoesaround-sigmodrec2024.pdf). *ACM SIGMOD Record*, volume 53, issue 2, pages 21–37. [doi:10.1145/3685980.3685984](https://doi.org/10.1145/3685980.3685984)
|
||||
[^32]: Lawrence Page, Sergey Brin, Rajeev Motwani, and Terry Winograd. [The PageRank Citation Ranking: Bringing Order to the Web](http://ilpubs.stanford.edu:8090/422/). Technical Report 1999-66, Stanford University InfoLab, November 1999. Archived at [perma.cc/UML9-UZHW](https://perma.cc/UML9-UZHW)
|
||||
[^33]: Nathan Bronson, Zach Amsden, George Cabrera, Prasad Chakka, Peter Dimov, Hui Ding, Jack Ferris, Anthony Giardullo, Sachin Kulkarni, Harry Li, Mark Marchukov, Dmitri Petrov, Lovro Puzar, Yee Jiun Song, and Venkat Venkataramani. [TAO: Facebook's Distributed Data Store for the Social Graph](https://www.usenix.org/conference/atc13/technical-sessions/presentation/bronson). At *USENIX Annual Technical Conference* (ATC), June 2013.
|
||||
[^33]: Nathan Bronson, Zach Amsden, George Cabrera, Prasad Chakka, Peter Dimov, Hui Ding, Jack Ferris, Anthony Giardullo, Sachin Kulkarni, Harry Li, Mark Marchukov, Dmitri Petrov, Lovro Puzar, Yee Jiun Song, and Venkat Venkataramani. [TAO: Facebook’s Distributed Data Store for the Social Graph](https://www.usenix.org/conference/atc13/technical-sessions/presentation/bronson). At *USENIX Annual Technical Conference* (ATC), June 2013.
|
||||
[^34]: Natasha Noy, Yuqing Gao, Anshu Jain, Anant Narayanan, Alan Patterson, and Jamie Taylor. [Industry-Scale Knowledge Graphs: Lessons and Challenges](https://cacm.acm.org/magazines/2019/8/238342-industry-scale-knowledge-graphs/fulltext). *Communications of the ACM*, volume 62, issue 8, pages 36–43, August 2019. [doi:10.1145/3331166](https://doi.org/10.1145/3331166)
|
||||
[^35]: Xiyang Feng, Guodong Jin, Ziyi Chen, Chang Liu, and Semih Salihoğlu. [KÙZU Graph Database Management System](https://www.cidrdb.org/cidr2023/papers/p48-jin.pdf). At *3th Annual Conference on Innovative Data Systems Research* (CIDR 2023), January 2023.
|
||||
[^36]: Maciej Besta, Emanuel Peter, Robert Gerstenberger, Marc Fischer, Michał Podstawski, Claude Barthels, Gustavo Alonso, Torsten Hoefler. [Demystifying Graph Databases: Analysis and Taxonomy of Data Organization, System Designs, and Graph Queries](https://arxiv.org/pdf/1910.09017.pdf). *arxiv.org*, October 2019.
|
||||
@ -1002,17 +1004,17 @@ query ChatApp {
|
||||
[^53]: Facebook. [The Open Graph protocol](https://ogp.me/), *ogp.me*. Archived at [perma.cc/C49A-GUSY](https://perma.cc/C49A-GUSY)
|
||||
[^54]: Matt Haughey. [Everything you ever wanted to know about unfurling but were afraid to ask /or/ How to make your site previews look amazing in Slack](https://medium.com/slack-developer-blog/everything-you-ever-wanted-to-know-about-unfurling-but-were-afraid-to-ask-or-how-to-make-your-e64b4bb9254). *medium.com*, November 2015. Archived at [perma.cc/C7S8-4PZN](https://perma.cc/C7S8-4PZN)
|
||||
[^55]: W3C RDF Working Group. [Resource Description Framework (RDF)](https://www.w3.org/RDF/). *w3.org*, February 2004.
|
||||
[^56]: Steve Harris, Andy Seaborne, and Eric Prud'hommeaux. [SPARQL 1.1 Query Language](https://www.w3.org/TR/sparql11-query/). W3C Recommendation, March 2013.
|
||||
[^56]: Steve Harris, Andy Seaborne, and Eric Prud’hommeaux. [SPARQL 1.1 Query Language](https://www.w3.org/TR/sparql11-query/). W3C Recommendation, March 2013.
|
||||
[^57]: Todd J. Green, Shan Shan Huang, Boon Thau Loo, and Wenchao Zhou. [Datalog and Recursive Query Processing](http://blogs.evergreen.edu/sosw/files/2014/04/Green-Vol5-DBS-017.pdf). *Foundations and Trends in Databases*, volume 5, issue 2, pages 105–195, November 2013. [doi:10.1561/1900000017](https://doi.org/10.1561/1900000017)
|
||||
[^58]: Stefano Ceri, Georg Gottlob, and Letizia Tanca. [What You Always Wanted to Know About Datalog (And Never Dared to Ask)](https://www.researchgate.net/profile/Letizia_Tanca/publication/3296132_What_you_always_wanted_to_know_about_Datalog_and_never_dared_to_ask/links/0fcfd50ca2d20473ca000000.pdf). *IEEE Transactions on Knowledge and Data Engineering*, volume 1, issue 1, pages 146–166, March 1989. [doi:10.1109/69.43410](https://doi.org/10.1109/69.43410)
|
||||
[^59]: Serge Abiteboul, Richard Hull, and Victor Vianu. [*Foundations of Databases*](http://webdam.inria.fr/Alice/). Addison-Wesley, 1995. ISBN: 9780201537710, available online at [*webdam.inria.fr/Alice*](http://webdam.inria.fr/Alice/)
|
||||
[^60]: Scott Meyer, Andrew Carter, and Andrew Rodriguez. [LIquid: The soul of a new graph database, Part 2](https://engineering.linkedin.com/blog/2020/liquid--the-soul-of-a-new-graph-database--part-2). *engineering.linkedin.com*, September 2020. Archived at [perma.cc/K9M4-PD6Q](https://perma.cc/K9M4-PD6Q)
|
||||
[^61]: Matt Bessey. [Why, after 6 years, I'm over GraphQL](https://bessey.dev/blog/2024/05/24/why-im-over-graphql/). *bessey.dev*, May 2024. Archived at [perma.cc/2PAU-JYRA](https://perma.cc/2PAU-JYRA)
|
||||
[^61]: Matt Bessey. [Why, after 6 years, I’m over GraphQL](https://bessey.dev/blog/2024/05/24/why-im-over-graphql/). *bessey.dev*, May 2024. Archived at [perma.cc/2PAU-JYRA](https://perma.cc/2PAU-JYRA)
|
||||
[^62]: Dominic Betts, Julián Domínguez, Grigori Melnik, Fernando Simonazzi, and Mani Subramanian. [*Exploring CQRS and Event Sourcing*](https://learn.microsoft.com/en-us/previous-versions/msp-n-p/jj554200%28v%3Dpandp.10%29). Microsoft Patterns & Practices, July 2012. ISBN: 1621140164, archived at [perma.cc/7A39-3NM8](https://perma.cc/7A39-3NM8)
|
||||
[^63]: Greg Young. [CQRS and Event Sourcing](https://www.youtube.com/watch?v=JHGkaShoyNs). At *Code on the Beach*, August 2014.
|
||||
[^64]: Greg Young. [CQRS Documents](https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf). *cqrs.wordpress.com*, November 2010. Archived at [perma.cc/X5R6-R47F](https://perma.cc/X5R6-R47F)
|
||||
[^65]: Devin Petersohn, Stephen Macke, Doris Xin, William Ma, Doris Lee, Xiangxi Mo, Joseph E. Gonzalez, Joseph M. Hellerstein, Anthony D. Joseph, and Aditya Parameswaran. [Towards Scalable Dataframe Systems](https://www.vldb.org/pvldb/vol13/p2033-petersohn.pdf). *Proceedings of the VLDB Endowment*, volume 13, issue 11, pages 2033–2046. [doi:10.14778/3407790.3407807](https://doi.org/10.14778/3407790.3407807)
|
||||
[^66]: Stavros Papadopoulos, Kushal Datta, Samuel Madden, and Timothy Mattson. [The TileDB Array Data Storage Manager](https://www.vldb.org/pvldb/vol10/p349-papadopoulos.pdf). *Proceedings of the VLDB Endowment*, volume 10, issue 4, pages 349–360, November 2016. [doi:10.14778/3025111.3025117](https://doi.org/10.14778/3025111.3025117)
|
||||
[^67]: Florin Rusu. [Multidimensional Array Data Management](https://faculty.ucmerced.edu/frusu/Papers/Report/2022-09-fntdb-arrays.pdf). *Foundations and Trends in Databases*, volume 12, numbers 2–3, pages 69–220, February 2023. [doi:10.1561/1900000069](https://doi.org/10.1561/1900000069)
|
||||
[^68]: Ed Targett. [Bloomberg, Man Group team up to develop open source "ArcticDB" database](https://www.thestack.technology/bloomberg-man-group-arcticdb-database-dataframe/). *thestack.technology*, March 2023. Archived at [perma.cc/M5YD-QQYV](https://perma.cc/M5YD-QQYV)
|
||||
[^69]: Dennis A. Benson, Ilene Karsch-Mizrachi, David J. Lipman, James Ostell, and David L. Wheeler. [GenBank](https://academic.oup.com/nar/article/36/suppl_1/D25/2507746). *Nucleic Acids Research*, volume 36, database issue, pages D25–D30, December 2007. [doi:10.1093/nar/gkm929](https://doi.org/10.1093/nar/gkm929)
|
||||
[^68]: Ed Targett. [Bloomberg, Man Group team up to develop open source “ArcticDB” database](https://www.thestack.technology/bloomberg-man-group-arcticdb-database-dataframe/). *thestack.technology*, March 2023. Archived at [perma.cc/M5YD-QQYV](https://perma.cc/M5YD-QQYV)
|
||||
[^69]: Dennis A. Benson, Ilene Karsch-Mizrachi, David J. Lipman, James Ostell, and David L. Wheeler. [GenBank](https://academic.oup.com/nar/article/36/suppl_1/D25/2507746). *Nucleic Acids Research*, volume 36, database issue, pages D25–D30, December 2007. [doi:10.1093/nar/gkm929](https://doi.org/10.1093/nar/gkm929)
|
@ -4,6 +4,8 @@ weight: 104
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||

|
||||
|
||||
> *生活中的一大痛苦是,每个人给事物起的名字都有一点点不对。这让世界上的一切都比换个名字后更难理解。计算机主要并不是在算术意义上进行计算。[...] 它们主要是归档系统。*
|
||||
>
|
||||
> [Richard Feynman](https://www.youtube.com/watch?v=EKWGGDXe5MA&t=296s),
|
||||
|
1013
content/zh/ch5.md
1013
content/zh/ch5.md
File diff suppressed because it is too large
Load Diff
1699
content/zh/ch6.md
1699
content/zh/ch6.md
File diff suppressed because it is too large
Load Diff
@ -4,747 +4,354 @@ weight: 207
|
||||
breadcrumbs: false
|
||||
---
|
||||
|
||||
> *Clearly, we must break away from the sequential and not limit the computers. We must state
|
||||
> definitions and provide for priorities and descriptions of data. We must state relationships, not
|
||||
> procedures.*
|
||||

|
||||
|
||||
> *显然,我们必须跳出顺序计算机指令的窠臼。我们必须叙述定义、提供优先级和数据描述。我们必须叙述关系,而不是过程。*
|
||||
>
|
||||
> Grace Murray Hopper, *Management and the Computer of the Future* (1962)
|
||||
> Grace Murray Hopper,《未来的计算机及其管理》(1962)
|
||||
|
||||
A distributed database typically distributes data across nodes in two ways:
|
||||
分布式数据库通常通过两种方式在节点间分布数据:
|
||||
|
||||
1. Having a copy of the same data on multiple nodes: this is *replication*, which we discussed in [Chapter 6](/en/ch6#ch_replication).
|
||||
2. If we don’t want every node to store all the data, we can split up a large amount of data into
|
||||
smaller *shards* or *partitions*, and store different shards on different nodes. We’ll discuss
|
||||
sharding in this chapter.
|
||||
1. 在多个节点上保存相同数据的副本:这是 *复制*,我们在 [第 6 章](/ch6#ch_replication) 中讨论过。
|
||||
2. 如果我们不想让每个节点都存储所有数据,我们可以将大量数据分割成更小的 *分片(shards)* 或 *分区(partitions)*,并将不同的分片存储在不同的节点上。我们将在本章讨论分片。
|
||||
|
||||
Normally, shards are defined in such a way that each piece of data (each record, row, or document)
|
||||
belongs to exactly one shard. There are various ways of achieving this, which we discuss in depth in
|
||||
this chapter. In effect, each shard is a small database of its own, although some database systems
|
||||
support operations that touch multiple shards at the same time.
|
||||
通常,分片的定义方式使得每条数据(每条记录、行或文档)恰好属于一个分片。有多种方法可以实现这一点,我们将在本章深入讨论。实际上,每个分片本身就是一个小型数据库,尽管某些数据库系统支持同时涉及多个分片的操作。
|
||||
|
||||
Sharding is usually combined with replication so that copies of each shard are stored on multiple
|
||||
nodes. This means that, even though each record belongs to exactly one shard, it may still be stored
|
||||
on several different nodes for fault tolerance.
|
||||
分片通常与复制结合使用,以便每个分片的副本存储在多个节点上。这意味着,即使每条记录属于恰好一个分片,它仍然可以存储在多个不同的节点上以提供容错能力。
|
||||
|
||||
A node may store more than one shard. If a single-leader replication model is used, the combination
|
||||
of sharding and replication can look like [Figure 7-1](/en/ch7#fig_sharding_replicas), for example. Each shard’s
|
||||
leader is assigned to one node, and its followers are assigned to other nodes. Each node may be the
|
||||
leader for some shards and a follower for other shards, but each shard still only has one leader.
|
||||
一个节点可能存储多个分片。如果使用单主复制模型,分片和复制的组合可能看起来像 [图 7-1](/ch7#fig_sharding_replicas),例如。每个分片的主节点被分配给一个节点,其从节点被分配给其他节点。每个节点可能是某些分片的主节点,同时是其他分片的从节点。
|
||||
|
||||
{{< figure src="/fig/ddia_0701.png" id="fig_sharding_replicas" caption="Figure 7-1. Combining replication and sharding: each node acts as leader for some shards and follower for other shards." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0701.png" id="fig_sharding_replicas" caption="图 7-1. 结合复制和分片:每个节点充当某些分片的主节点,同时充当其他分片的从节点。" class="w-full my-4" >}}
|
||||
|
||||
Everything we discussed in [Chapter 6](/en/ch6#ch_replication) about replication of databases applies equally to
|
||||
replication of shards. Since the choice of sharding scheme is mostly independent of the choice of
|
||||
replication scheme, we will ignore replication in this chapter for the sake of simplicity.
|
||||
我们在 [第 6 章](/ch6#ch_replication) 中讨论的关于数据库复制的所有内容同样适用于分片的复制。由于分片方案的选择大部分独立于复制方案的选择,为了简单起见,我们将在本章中忽略复制。
|
||||
|
||||
--------
|
||||
|
||||
> [!TIP] 分片与分区
|
||||
> [!TIP] 分片和分区
|
||||
|
||||
What we call a *shard* in this chapter has many different names depending on which software you’re
|
||||
using: it’s called a *partition* in Kafka, a *range* in CockroachDB, a *region* in HBase and TiDB, a
|
||||
*tablet* in Bigtable and YugabyteDB, a *vnode* in Cassandra, ScyllaDB, and Riak, and a *vBucket* in
|
||||
Couchbase, to name just a few.
|
||||
在本章中我们称之为 *分片* 的东西,根据你使用的软件不同有许多不同的名称:在 Kafka 中称为 *分区(partition)*,在 CockroachDB 中称为 *范围(range)*,在 HBase 和 TiDB 中称为 *区域(region)*,在 Bigtable 和 YugabyteDB 中称为 *表块(tablet)*,在 Cassandra、ScyllaDB 和 Riak 中称为 *虚节点(vnode)*,在 Couchbase 中称为 *虚桶(vBucket)*,仅举几例。
|
||||
|
||||
Some databases treat partitions and shards as two distinct concepts. For example, in PostgreSQL,
|
||||
partitioning is a way of splitting a large table into several files that are stored on the same
|
||||
machine (which has several advantages, such as making it very fast to delete an entire partition),
|
||||
whereas sharding splits a dataset across multiple machines [^1] [^2].
|
||||
In many other systems, partitioning is just another word for sharding.
|
||||
一些数据库将分区和分片视为两个不同的概念。例如,在 PostgreSQL 中,分区是将大表拆分为存储在同一台机器上的多个文件的方法(这有几个优点,例如可以非常快速地删除整个分区),而分片则是将数据集拆分到多台机器上 [^1] [^2]。在许多其他系统中,分区只是分片的另一个词。
|
||||
|
||||
While *partitioning* is quite descriptive, the term *sharding* is perhaps surprising. According to
|
||||
one theory, the term arose from the online role-play game *Ultima Online*, in which a magic crystal
|
||||
was shattered into pieces, and each of those shards refracted a copy of the game world [^3].
|
||||
The term *shard* thus came to mean one of a set of parallel game servers, and later was carried over
|
||||
to databases. Another theory is that *shard* was originally an acronym of *System for Highly
|
||||
Available Replicated Data*—reportedly a 1980s database, details of which are lost to history.
|
||||
虽然 *分区* 相当具有描述性,但 *分片* 这个术语可能令人惊讶。根据一种理论,该术语源于在线角色扮演游戏《网络创世纪》(Ultima Online),其中一块魔法水晶被打碎成碎片,每个碎片都折射出游戏世界的副本 [^3]。*分片* 一词因此用来指一组并行游戏服务器中的一个,后来被引入数据库。另一种理论是 *分片* 最初是 *高可用复制数据系统*(System for Highly Available Replicated Data)的缩写——据说是 1980 年代的一个数据库,其细节已经失传。
|
||||
|
||||
By the way, partitioning has nothing to do with *network partitions* (netsplits), a type of fault in
|
||||
the network between nodes. We will discuss such faults in [Chapter 9](/en/ch9#ch_distributed).
|
||||
顺便说一下,分区与 *网络分区*(netsplits)无关,后者是节点之间网络中的一种故障。我们将在 [第 9 章](/ch9#ch_distributed) 中讨论此类故障。
|
||||
|
||||
--------
|
||||
|
||||
## 分片的利与弊 {#sec_sharding_reasons}
|
||||
|
||||
The primary reason for sharding a database is *scalability*: it’s a solution if the volume of data
|
||||
or the write throughput has become too great for a single node to handle, as it allows you to spread
|
||||
that data and those writes across multiple nodes. (If read throughput is the problem, you don’t
|
||||
necessarily need sharding—you can use *read scaling* as discussed in [Chapter 6](/en/ch6#ch_replication).)
|
||||
对数据库进行分片的主要原因是 *可伸缩性*:如果数据量或写吞吐量已经超出单个节点的处理能力,这是一个解决方案,它允许你将数据和写入分散到多个节点上。(如果读吞吐量是问题,你不一定需要分片——你可以使用 [第 6 章](/ch6#ch_replication) 中讨论的 *读扩展*。)
|
||||
|
||||
In fact, sharding is one of the main tools we have for achieving *horizontal scaling* (a *scale-out*
|
||||
architecture), as discussed in [“Shared-Memory, Shared-Disk, and Shared-Nothing Architecture”](/en/ch2#sec_introduction_shared_nothing): that is, allowing a system to
|
||||
grow its capacity not by moving to a bigger machine, but by adding more (smaller) machines. If you
|
||||
can divide the workload such that each shard handles a roughly equal share, you can then assign
|
||||
those shards to different machines in order to process their data and queries in parallel.
|
||||
事实上,分片是我们实现 *水平扩展*(*横向扩展* 架构)的主要工具之一,如 ["共享内存、共享磁盘和无共享架构"](/ch2#sec_introduction_shared_nothing) 中所讨论的:即,允许系统通过添加更多(较小的)机器而不是转移到更大的机器来增长其容量。如果你可以划分工作负载,使每个分片处理大致相等的份额,那么你可以将这些分片分配给不同的机器,以便并行处理它们的数据和查询。
|
||||
|
||||
While replication is useful at both small and large scale, because it enables fault tolerance and
|
||||
offline operation, sharding is a heavyweight solution that is mostly relevant at large scale. If
|
||||
your data volume and write throughput are such that you can process them on a single machine (and a
|
||||
single machine can do a lot nowadays!), it’s often better to avoid sharding and stick with a
|
||||
single-shard database.
|
||||
虽然复制在小规模和大规模上都很有用,因为它支持容错和离线操作,但分片是一个重量级解决方案,主要在大规模场景下才有意义。如果你的数据量和写吞吐量可以在单台机器上处理(而单台机器现在可以做很多事情!),通常最好避免分片并坚持使用单分片数据库。
|
||||
|
||||
The reason for this recommendation is that sharding often adds complexity: you typically have to
|
||||
decide which records to put in which shard by choosing a *partition key*; all records with the
|
||||
same partition key are placed in the same shard [^4].
|
||||
This choice matters because accessing a record is fast if you know which shard it’s in, but if you
|
||||
don’t know the shard you have to do an inefficient search across all shards, and the sharding scheme
|
||||
is difficult to change.
|
||||
推荐这样做的原因是分片通常会增加复杂性:你通常必须通过选择 *分区键* 来决定将哪些记录放在哪个分片中;具有相同分区键的所有记录都放在同一个分片中 [^4]。这个选择很重要,因为如果你知道记录在哪个分片中,访问记录会很快,但如果你不知道分片,你必须在所有分片中进行低效的搜索,而且分片方案很难更改。
|
||||
|
||||
Thus, sharding often works well for key-value data, where you can easily shard by key, but it’s
|
||||
harder with relational data where you may want to search by a secondary index, or join records that
|
||||
may be distributed across different shards. We will discuss this further in
|
||||
[“Sharding and Secondary Indexes”](/en/ch7#sec_sharding_secondary_indexes).
|
||||
因此,分片通常适用于键值数据,你可以轻松地按键进行分片,但对于关系数据则较难,因为你可能想要通过二级索引搜索,或连接可能分布在不同分片中的记录。我们将在 ["分片与二级索引"](/ch7#sec_sharding_secondary_indexes) 中进一步讨论这个问题。
|
||||
|
||||
Another problem with sharding is that a write may need to update related records in several
|
||||
different shards. While transactions on a single node are quite common (see [Chapter 8](/en/ch8#ch_transactions)),
|
||||
ensuring consistency across multiple shards requires a *distributed transaction*. As we shall see in
|
||||
[Chapter 8](/en/ch8#ch_transactions), distributed transactions are available in some databases, but they are usually
|
||||
much slower than single-node transactions, may become a bottleneck for the system as a whole, and
|
||||
some systems don’t support them at all.
|
||||
分片的另一个问题是写入可能需要更新多个不同分片中的相关记录。虽然单节点上的事务相当常见(见 [第 8 章](/ch8#ch_transactions)),但确保跨多个分片的一致性需要 *分布式事务*。正如我们将在 [第 8 章](/ch8#ch_transactions) 中看到的,分布式事务在某些数据库中可用,但它们通常比单节点事务慢得多,可能成为整个系统的瓶颈,有些系统根本不支持它们。
|
||||
|
||||
Some systems use sharding even on a single machine, typically running one single-threaded process
|
||||
per CPU core to make use of the parallelism in the CPU, or to take advantage of a *nonuniform memory
|
||||
access* (NUMA) architecture in which some banks of memory are closer to one CPU than to others [^5].
|
||||
For example, Redis, VoltDB, and FoundationDB use one process per core, and rely on sharding to
|
||||
spread load across CPU cores in the same machine [^6].
|
||||
一些系统即使在单台机器上也使用分片,通常每个 CPU 核心运行一个单线程进程以利用 CPU 中的并行性,或者利用 *非一致性内存访问*(NUMA)架构,其中某些内存库比其他内存库更接近某个 CPU [^5]。例如,Redis、VoltDB 和 FoundationDB 每个核心使用一个进程,并依靠分片在同一台机器的 CPU 核心之间分散负载 [^6]。
|
||||
|
||||
### 面向多租户的分片 {#sec_sharding_multitenancy}
|
||||
|
||||
Software as a Service (SaaS) products and cloud services are often *multitenant*, where each tenant
|
||||
is a customer. Multiple users may have logins on the same tenant, but each tenant has a
|
||||
self-contained dataset that is separate from other tenants. For example, in an email marketing
|
||||
service, each business that signs up is typically a separate tenant, since one business’s newsletter
|
||||
signups, delivery data etc. are separate from those of other businesses.
|
||||
软件即服务(SaaS)产品和云服务通常是 *多租户* 的,其中每个租户是一个客户。多个用户可能在同一租户上拥有登录帐户,但每个租户都有一个独立的数据集,与其他租户分开。例如,在电子邮件营销服务中,每个注册的企业通常是一个单独的租户,因为一个企业的通讯订阅、投递数据等与其他企业的数据是分开的。
|
||||
|
||||
Sometimes sharding is used to implement multitenant systems: either each tenant is given a separate
|
||||
shard, or multiple small tenants may be grouped together into a larger shard. These shards might be
|
||||
physically separate databases (which we previously touched on in [“Embedded storage engines”](/en/ch4#sidebar_embedded)), or
|
||||
separately manageable portions of a larger logical database [^7].
|
||||
Using sharding for multitenancy has several advantages:
|
||||
有时分片用于实现多租户系统:要么每个租户被分配一个单独的分片,要么多个小租户可能被分组到一个更大的分片中。这些分片可能是物理上分离的数据库(我们之前在 ["嵌入式存储引擎"](/ch4#sidebar_embedded) 中提到过),或者是更大逻辑数据库的可单独管理部分 [^7]。使用分片实现多租户有几个优点:
|
||||
|
||||
Resource isolation
|
||||
: If one tenant performs a computationally expensive operation, it is less likely that other
|
||||
tenants’ performance will be affected if they are running on different shards.
|
||||
资源隔离
|
||||
: 如果一个租户执行计算密集型操作,如果它们在不同的分片上运行,其他租户的性能受影响的可能性较小。
|
||||
|
||||
Permission isolation
|
||||
: If there is a bug in your access control logic, it’s less likely that you will accidentally give
|
||||
one tenant access to another tenant’s data if those tenants’ datasets are stored physically
|
||||
separately from each other.
|
||||
权限隔离
|
||||
: 如果你的访问控制逻辑中存在错误,如果这些租户的数据集彼此物理分离存储,你意外地给一个租户访问另一个租户数据的可能性较小。
|
||||
|
||||
Cell-based architecture
|
||||
: You can apply sharding not only at the data storage level, but also for the services running your
|
||||
application code. In a *cell-based architecture*, the services and storage for a particular set of
|
||||
tenants are grouped into a self-contained *cell*, and different cells are set up such that they
|
||||
can run largely independently from each other. This approach provides *fault isolation*: that is,
|
||||
a fault in one cell remains limited to that cell, and tenants in other cells are not affected [^8].
|
||||
基于单元的架构
|
||||
: 你不仅可以在数据存储级别应用分片,还可以为运行应用程序代码的服务应用分片。在 *基于单元的架构* 中,特定租户集的服务和存储被分组到一个自包含的 *单元* 中,不同的单元被设置为可以在很大程度上彼此独立运行。这种方法提供了 *故障隔离*:即,一个单元中的故障仅限于该单元,其他单元中的租户不受影响 [^8]。
|
||||
|
||||
Per-tenant backup and restore
|
||||
: Backing up each tenant’s shard separately makes it possible to restore a tenant’s state from a
|
||||
backup without affecting other tenants, which can be useful in case the tenant accidentally
|
||||
deletes or overwrites important data [^9].
|
||||
按租户备份和恢复
|
||||
: 单独备份每个租户的分片使得可以从备份中恢复租户的状态而不影响其他租户,这在租户意外删除或覆盖重要数据的情况下很有用 [^9]。
|
||||
|
||||
Regulatory compliance
|
||||
: Data privacy regulation such as the GDPR gives individuals the right to access and delete all data
|
||||
stored about them. If each person’s data is stored in a separate shard, this translates into
|
||||
simple data export and deletion operations on their shard [^10].
|
||||
法规合规性
|
||||
: 数据隐私法规(如 GDPR)赋予个人访问和删除存储的所有关于他们的数据的权利。如果每个人的数据存储在单独的分片中,这就转化为对其分片的简单数据导出和删除操作 [^10]。
|
||||
|
||||
Data residence
|
||||
: If a particular tenant’s data needs to be stored in a particular jurisdiction in order to comply
|
||||
with data residency laws, a region-aware database can allow you to assign that tenant’s shard to a particular region.
|
||||
数据驻留
|
||||
: 如果特定租户的数据需要存储在特定司法管辖区以符合数据驻留法律,具有区域感知的数据库可以允许你将该租户的分片分配给特定区域。
|
||||
|
||||
Gradual schema rollout
|
||||
: Schema migrations (previously discussed in [“Schema flexibility in the document model”](/en/ch3#sec_datamodels_schema_flexibility)) can be rolled
|
||||
out gradually, one tenant at a time. This reduces risk, as you can detect problems before they
|
||||
affect all tenants, but it can be difficult to do transactionally [^11].
|
||||
渐进式模式推出
|
||||
: 模式迁移(之前在 ["文档模型中的模式灵活性"](/ch3#sec_datamodels_schema_flexibility) 中讨论过)可以逐步推出,一次一个租户。这降低了风险,因为你可以在影响所有租户之前检测到问题,但很难以事务方式执行 [^11]。
|
||||
|
||||
The main challenges around using sharding for multitenancy are:
|
||||
使用分片实现多租户的主要挑战是:
|
||||
|
||||
* It assumes that each individual tenant is small enough to fit on a single node. If that is not the
|
||||
case, and you have a single tenant that’s too big for one machine, you would need to additionally
|
||||
perform sharding within a single tenant, which brings us back to the topic of sharding for
|
||||
scalability [^12].
|
||||
* If you have many small tenants, then creating a separate shard for each one may incur too much
|
||||
overhead. You could group several small tenants together into a bigger shard, but then you have
|
||||
the problem of how you move tenants from one shard to another as they grow.
|
||||
* If you ever need to support features that connect data across multiple tenants, these become
|
||||
harder to implement if you need to join data across multiple shards.
|
||||
* 它假设每个单独的租户都足够小,可以适应单个节点。如果情况并非如此,并且你有一个对于一台机器来说太大的租户,你将需要在单个租户内额外执行分片,这将我们带回到为可伸缩性进行分片的主题 [^12]。
|
||||
* 如果你有许多小租户,那么为每个租户创建单独的分片可能会产生太多开销。你可以将几个小租户组合到一个更大的分片中,但随后你会遇到如何在租户增长时将其从一个分片移动到另一个分片的问题。
|
||||
* 如果你需要支持跨多个租户连接数据的功能,如果你需要跨多个分片连接数据,这些功能将变得更难实现。
|
||||
|
||||
|
||||
|
||||
## 键值数据的分片 {#sec_sharding_key_value}
|
||||
|
||||
Say you have a large amount of data, and you want to shard it. How do you decide which records to
|
||||
store on which nodes?
|
||||
假设你有大量数据,并且想要对其进行分片。如何决定将哪些记录存储在哪些节点上?
|
||||
|
||||
Our goal with sharding is to spread the data and the query load evenly across nodes. If every node
|
||||
takes a fair share, then—in theory—10 nodes should be able to handle 10 times as much data and 10
|
||||
times the read and write throughput of a single node (ignoring replication). Moreover, if we add or
|
||||
remove a node, we want to be able to *rebalance* the load so that it is evenly distributed across
|
||||
the 11 (when adding) or the remaining 9 (when removing) nodes.
|
||||
我们进行分片的目标是将数据和查询负载均匀地分布在各节点上。如果每个节点承担公平的份额,那么理论上——10 个节点应该能够处理 10 倍的数据量和 10 倍单个节点的读写吞吐量(忽略复制)。此外,如果我们添加或删除节点,我们希望能够 *再平衡* 负载,使其在添加时均匀分布在 11 个节点上(或删除时在剩余的 9 个节点上)。
|
||||
|
||||
If the sharding is unfair, so that some shards have more data or queries than others, we call it
|
||||
*skewed*. The presence of skew makes sharding much less effective. In an extreme case, all the load
|
||||
could end up on one shard, so 9 out of 10 nodes are idle and your bottleneck is the single busy
|
||||
node. A shard with disproportionately high load is called a *hot shard* or *hot spot*. If there’s
|
||||
one key with a particularly high load (e.g., a celebrity in a social network), we call it a *hot key*.
|
||||
如果分片不公平,使得某些分片比其他分片有更多的数据或查询,我们称之为 *倾斜*。倾斜的存在使分片的效果大打折扣。在极端情况下,所有负载可能最终集中在一个分片上,因此 10 个节点中有 9 个处于空闲状态,你的瓶颈是单个繁忙的节点。具有不成比例高负载的分片称为 *热分片* 或 *热点*。如果有一个键具有特别高的负载(例如,社交网络中的名人),我们称之为 *热键*。
|
||||
|
||||
Therefore we need an algorithm that takes as input the partition key of a record, and tells us which
|
||||
shard that record is in. In a key-value store the partition key is usually the key, or the first
|
||||
part of the key. In a relational model the partition key might be some column of a table (not
|
||||
necessarily its primary key). That algorithm needs to be amenable to rebalancing in order to relieve
|
||||
hot spots.
|
||||
因此,我们需要一种算法,它以记录的分区键作为输入,并告诉我们该记录在哪个分片中。在键值存储中,分区键通常是键,或键的第一部分。在关系模型中,分区键可能是表的某一列(不一定是其主键)。该算法需要能够进行再平衡以缓解热点。
|
||||
|
||||
|
||||
### 按键的范围分片 {#sec_sharding_key_range}
|
||||
|
||||
One way of sharding is to assign a contiguous range of partition keys (from some minimum to some
|
||||
maximum) to each shard, like the volumes of a paper encyclopedia, as illustrated in
|
||||
[Figure 7-2](/en/ch7#fig_sharding_encyclopedia). In this example, an entry’s partition key is its title. If you want
|
||||
to look up the entry for a particular title, you can easily determine which shard contains that
|
||||
entry by finding the volume whose key range contains the title you’re looking for, and thus pick the
|
||||
correct book off the shelf.
|
||||
一种分片方法是为每个分片分配一个连续的分区键范围(从某个最小值到某个最大值),就像纸质百科全书的卷一样,如 [图 7-2](/ch7#fig_sharding_encyclopedia) 所示。在这个例子中,条目的分区键是其标题。如果你想查找特定标题的条目,你可以通过找到键范围包含你要查找标题的卷来轻松确定哪个分片包含该条目,从而从书架上挑选正确的书。
|
||||
|
||||
{{< figure src="/fig/ddia_0702.png" id="fig_sharding_encyclopedia" caption="Figure 7-2. A print encyclopedia is sharded by key range." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0702.png" id="fig_sharding_encyclopedia" caption="图 7-2. 印刷版百科全书按键范围分片。" class="w-full my-4" >}}
|
||||
|
||||
The ranges of keys are not necessarily evenly spaced, because your data may not be evenly
|
||||
distributed. For example, in [Figure 7-2](/en/ch7#fig_sharding_encyclopedia), volume 1 contains words starting with A
|
||||
and B, but volume 12 contains words starting with T, U, V, W, X, Y, and Z. Simply having one volume
|
||||
per two letters of the alphabet would lead to some volumes being much bigger than others. In order
|
||||
to distribute the data evenly, the shard boundaries need to adapt to the data.
|
||||
键的范围不一定是均匀分布的,因为你的数据可能不是均匀分布的。例如,在 [图 7-2](/ch7#fig_sharding_encyclopedia) 中,第 1 卷包含以 A 和 B 开头的单词,但第 12 卷包含以 T、U、V、W、X、Y 和 Z 开头的单词。简单地为字母表的每两个字母分配一卷会导致某些卷比其他卷大得多。为了均匀分布数据,分片边界需要适应数据。
|
||||
|
||||
The shard boundaries might be chosen manually by an administrator, or the database can choose them
|
||||
automatically. Manual key-range sharding is used by Vitess (a sharding layer for MySQL), for
|
||||
example; the automatic variant is used by Bigtable, its open source equivalent HBase, the
|
||||
range-based sharding option in MongoDB, CockroachDB, RethinkDB, and FoundationDB [^6]. YugabyteDB offers both manual and automatic
|
||||
tablet splitting.
|
||||
分片边界可能由管理员手动选择,或者数据库可以自动选择它们。手动键范围分片例如被 Vitess(MySQL 的分片层)使用;自动变体被 Bigtable、其开源等价物 HBase、MongoDB 中基于范围的分片选项、CockroachDB、RethinkDB 和 FoundationDB 使用 [^6]。YugabyteDB 提供手动和自动表块分割两种选项。
|
||||
|
||||
Within each shard, keys are stored in sorted order (e.g., in a B-tree or SSTables, as discussed in
|
||||
[Chapter 4](/en/ch4#ch_storage)). This has the advantage that range scans are easy, and you can treat the key as a
|
||||
concatenated index in order to fetch several related records in one query (see
|
||||
[“Multidimensional and Full-Text Indexes”](/en/ch4#sec_storage_multidimensional)). For example, consider an application that stores data from a
|
||||
network of sensors, where the key is the timestamp of the measurement. Range scans are very useful
|
||||
in this case, because they let you easily fetch, say, all the readings from a particular month.
|
||||
在每个分片内,键以排序顺序存储(例如,在 B 树或 SSTable 中,如 [第 4 章](/ch4#ch_storage) 中所讨论的)。这样做的优点是范围扫描很容易,你可以将键视为连接索引,以便在一个查询中获取多个相关记录(参见 ["多维和全文索引"](/ch4#sec_storage_multidimensional))。例如,考虑一个存储传感器网络数据的应用程序,其中键是测量的时间戳。范围扫描在这种情况下非常有用,因为它们让你可以轻松获取,比如说,特定月份的所有读数。
|
||||
|
||||
A downside of key range sharding is that you can easily get a hot shard if there are a
|
||||
lot of writes to nearby keys. For example, if the key is a timestamp, then the shards correspond to
|
||||
ranges of time—e.g., one shard per month. Unfortunately, if you write data from the sensors to the
|
||||
database as the measurements happen, all the writes end up going to the same shard (the one for
|
||||
this month), so that shard can be overloaded with writes while others sit idle [^13].
|
||||
键范围分片的一个缺点是,如果有大量对相邻键的写入,你很容易得到一个热分片。例如,如果键是时间戳,那么分片对应于时间范围——例如,每个月一个分片。不幸的是,如果你在测量发生时将传感器数据写入数据库,所有写入最终都会进入同一个分片(本月的分片),因此该分片可能会因写入而过载,而其他分片则处于空闲状态 [^13]。
|
||||
|
||||
To avoid this problem in the sensor database, you need to use something other than the timestamp as
|
||||
the first element of the key. For example, you could prefix each timestamp with the sensor ID so
|
||||
that the key ordering is first by sensor ID and then by timestamp. Assuming you have many sensors
|
||||
active at the same time, the write load will end up more evenly spread across the shards. The
|
||||
downside is that when you want to fetch the values of multiple sensors within a time range, you now
|
||||
need to perform a separate range query for each sensor.
|
||||
为了避免传感器数据库中的这个问题,你需要使用时间戳以外的东西作为键的第一个元素。例如,你可以在每个时间戳前加上传感器 ID,使键排序首先按传感器 ID,然后按时间戳。假设你有许多传感器同时活动,写入负载最终会更均匀地分布在各个分片上。缺点是当你想要在一个时间范围内获取多个传感器的值时,你现在需要为每个传感器执行单独的范围查询。
|
||||
|
||||
#### 重新平衡键范围分片数据 {#rebalancing-key-range-sharded-data}
|
||||
|
||||
When you first set up your database, there are no key ranges to split into shards. Some databases,
|
||||
such as HBase and MongoDB, allow you to configure an initial set of shards on an empty database,
|
||||
which is called *pre-splitting*. This requires that you already have some idea of what the key
|
||||
distribution is going to look like, so that you can choose appropriate key range boundaries [^14].
|
||||
当你首次设置数据库时,没有键范围可以分割成分片。一些数据库,如 HBase 和 MongoDB,允许你在空数据库上配置一组初始分片,这称为 *预分割*。这要求你已经对键分布将会是什么样子有所了解,以便你可以选择适当的键范围边界 [^14]。
|
||||
|
||||
Later on, as your data volume and write throughput grow, a system with key-range sharding grows by
|
||||
splitting an existing shard into two or more smaller shards, each of which holds a contiguous
|
||||
sub-range of the original shard’s key range. The resulting smaller shards can then be distributed
|
||||
across multiple nodes. If large amounts of data are deleted, you may also need to merge several
|
||||
adjacent shards that have become small into one bigger one.
|
||||
This process is similar to what happens at the top level of a B-tree (see [“B-Trees”](/en/ch4#sec_storage_b_trees)).
|
||||
后来,随着你的数据量和写吞吐量增长,具有键范围分片的系统通过将现有分片分割成两个或更多较小的分片来增长,每个分片都保存原始分片键范围的连续子范围。然后可以将生成的较小分片分布在多个节点上。如果删除了大量数据,你可能还需要将几个相邻的已变小的分片合并为一个更大的分片。这个过程类似于 B 树顶层发生的事情(参见 ["B 树"](/ch4#sec_storage_b_trees))。
|
||||
|
||||
With databases that manage shard boundaries automatically, a shard split is typically triggered by:
|
||||
对于自动管理分片边界的数据库,分片分割通常由以下触发:
|
||||
|
||||
* the shard reaching a configured size (for example, on HBase, the default is 10 GB), or
|
||||
* in some systems, the write throughput being persistently above some threshold. Thus, a hot shard
|
||||
may be split even if it is not storing a lot of data, so that its write load can be distributed more uniformly.
|
||||
* 分片达到配置的大小(例如,在 HBase 上,默认值为 10 GB),或
|
||||
* 在某些系统中,写吞吐量持续高于某个阈值。因此,即使热分片没有存储大量数据,也可能被分割,以便其写入负载可以更均匀地分布。
|
||||
|
||||
An advantage of key-range sharding is that the number of shards adapts to the data volume. If there
|
||||
is only a small amount of data, a small number of shards is sufficient, so overheads are small; if
|
||||
there is a huge amount of data, the size of each individual shard is limited to a configurable maximum [^15].
|
||||
键范围分片的一个优点是分片数量适应数据量。如果只有少量数据,少量分片就足够了,因此开销很小;如果有大量数据,每个单独分片的大小被限制在可配置的最大值 [^15]。
|
||||
|
||||
A downside of this approach is that splitting a shard is an expensive operation, since it requires
|
||||
all of its data to be rewritten into new files, similarly to a compaction in a log-structured
|
||||
storage engine. A shard that needs splitting is often also one that is under high load, and the cost
|
||||
of splitting can exacerbate that load, risking it becoming overloaded.
|
||||
这种方法的一个缺点是分割分片是一项昂贵的操作,因为它需要将其所有数据重写到新文件中,类似于日志结构存储引擎中的压实。需要分割的分片通常也是处于高负载下的分片,分割的成本可能会加剧该负载,有使其过载的风险。
|
||||
|
||||
### 按键的哈希分片 {#sec_sharding_hash}
|
||||
|
||||
Key-range sharding is useful if you want records with nearby (but different) partition keys to be
|
||||
grouped into the same shard; for example, this might be the case with timestamps. If you don’t care
|
||||
whether partition keys are near each other (e.g., if they are tenant IDs in a multitenant
|
||||
application), a common approach is to first hash the partition key before mapping it to a shard.
|
||||
键范围分片在你希望具有相邻(但不同)分区键的记录被分组到同一个分片中时很有用;例如,如果是时间戳,这可能就是这种情况。如果你不关心分区键是否彼此接近(例如,如果它们是多租户应用程序中的租户 ID),一种常见方法是先对分区键进行哈希,然后将其映射到分片。
|
||||
|
||||
A good hash function takes skewed data and makes it uniformly distributed. Say you have a 32-bit
|
||||
hash function that takes a string. Whenever you give it a new string, it returns a seemingly random
|
||||
number between 0 and 232 − 1. Even if the input strings are very similar, their hashes are evenly
|
||||
distributed across that range of numbers (but the same input always produces the same output).
|
||||
一个好的哈希函数接受倾斜的数据并使其均匀分布。假设你有一个 32 位哈希函数,它接受一个字符串。每当你给它一个新字符串时,它返回一个介于 0 和 2³² − 1 之间的看似随机的数字。即使输入字符串非常相似,它们的哈希值也会均匀分布在该数字范围内(但相同的输入总是产生相同的输出)。
|
||||
|
||||
For sharding purposes, the hash function need not be cryptographically strong: for example, MongoDB
|
||||
uses MD5, whereas Cassandra and ScyllaDB use Murmur3. Many programming languages have simple hash
|
||||
functions built in (as they are used for hash tables), but they may not be suitable for sharding:
|
||||
for example, in Java’s `Object.hashCode()` and Ruby’s `Object#hash`, the same key may have a
|
||||
different hash value in different processes, making them unsuitable for sharding [^16].
|
||||
出于分片目的,哈希函数不需要是密码学强度的:例如,MongoDB 使用 MD5,而 Cassandra 和 ScyllaDB 使用 Murmur3。许多编程语言都内置了简单的哈希函数(因为它们用于哈希表),但它们可能不适合分片:例如,在 Java 的 `Object.hashCode()` 和 Ruby 的 `Object#hash` 中,相同的键在不同的进程中可能有不同的哈希值,使它们不适合分片 [^16]。
|
||||
|
||||
#### 哈希取模节点数 {#hash-modulo-number-of-nodes}
|
||||
|
||||
Once you have hashed the key, how do you choose which shard to store it in? Maybe your first thought
|
||||
is to take the hash value *modulo* the number of nodes in the system (using the `%` operator in many
|
||||
programming languages). For example, *hash*(*key*) % 10 would return a number between
|
||||
0 and 9 (if we write the hash as a decimal number, the hash % 10 would be the last digit).
|
||||
If we have 10 nodes, numbered 0 to 9, that seems like an easy way of assigning each key to a node.
|
||||
一旦你对键进行了哈希,如何选择将其存储在哪个分片中?也许你的第一个想法是取哈希值 *模* 系统中的节点数(在许多编程语言中使用 `%` 运算符)。例如,*hash*(*key*) % 10 将返回 0 到 9 之间的数字(如果我们将哈希写为十进制数,hash % 10 将是最后一位数字)。如果我们有 10 个节点,编号从 0 到 9,这似乎是将每个键分配给节点的简单方法。
|
||||
|
||||
The problem with the *mod N* approach is that if the number of nodes *N* changes, most of the keys
|
||||
have to be moved from one node to another. [Figure 7-3](/en/ch7#fig_sharding_hash_mod_n) shows what happens when you
|
||||
have three nodes and add a fourth. Before the rebalancing, node 0 stored the keys whose hashes are
|
||||
0, 3, 6, 9, and so on. After adding the fourth node, the key with hash 3 has moved to node 3, the
|
||||
key with hash 6 has moved to node 2, the key with hash 9 has moved to node 1, and so on.
|
||||
*mod N* 方法的问题是,如果节点数 *N* 发生变化,大多数键必须从一个节点移动到另一个节点。[图 7-3](/ch7#fig_sharding_hash_mod_n) 显示了当你有三个节点并添加第四个节点时会发生什么。在再平衡之前,节点 0 存储哈希值为 0、3、6、9 等的键。添加第四个节点后,哈希值为 3 的键已移动到节点 3,哈希值为 6 的键已移动到节点 2,哈希值为 9 的键已移动到节点 1,依此类推。
|
||||
|
||||
{{< figure src="/fig/ddia_0703.png" id="fig_sharding_hash_mod_n" caption="Figure 7-3. Assigning keys to nodes by hashing the key and taking it modulo the number of nodes. Changing the number of nodes results in many keys moving from one node to another." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0703.png" id="fig_sharding_hash_mod_n" caption="图 7-3. 通过对键进行哈希并取模节点数来将键分配给节点。更改节点数会导致许多键从一个节点移动到另一个节点。" class="w-full my-4" >}}
|
||||
|
||||
The *mod N* function is easy to compute, but it leads to very inefficient rebalancing because there
|
||||
is a lot of unnecessary movement of records from one node to another. We need an approach that
|
||||
doesn’t move data around more than necessary.
|
||||
*mod N* 函数易于计算,但它导致非常低效的再平衡,因为存在大量不必要的记录从一个节点移动到另一个节点。我们需要一种不会移动超过必要数据的方法。
|
||||
|
||||
#### 固定数量的分片 {#fixed-number-of-shards}
|
||||
|
||||
One simple but widely-used solution is to create many more shards than there are nodes, and to
|
||||
assign several shards to each node. For example, a database running on a cluster of 10 nodes may be
|
||||
split into 1,000 shards from the outset so that 100 shards are assigned to each node. A key is then
|
||||
stored in shard number *hash*(*key*) % 1,000, and the system separately keeps track of
|
||||
which shard is stored on which node.
|
||||
一个简单但广泛使用的解决方案是创建比节点多得多的分片,并为每个节点分配多个分片。例如,在 10 个节点的集群上运行的数据库可能从一开始就被分成 1,000 个分片,以便每个节点分配 100 个分片。然后将键存储在分片号 *hash*(*key*) % 1,000 中,系统单独跟踪哪个分片存储在哪个节点上。
|
||||
|
||||
Now, if a node is added to the cluster, the system can reassign some of the shards from existing
|
||||
nodes to the new node until they are fairly distributed once again. This process is illustrated in
|
||||
[Figure 7-4](/en/ch7#fig_sharding_rebalance_fixed). If a node is removed from the cluster, the same happens in reverse.
|
||||
现在,如果向集群添加一个节点,系统可以从现有节点重新分配一些分片到新节点,直到它们再次公平分布。这个过程在 [图 7-4](/ch7#fig_sharding_rebalance_fixed) 中说明。如果从集群中删除节点,则反向发生相同的事情。
|
||||
|
||||
{{< figure src="/fig/ddia_0704.png" id="fig_sharding_rebalance_fixed" caption="Figure 7-4. Adding a new node to a database cluster with multiple shards per node." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0704.png" id="fig_sharding_rebalance_fixed" caption="图 7-4. 向每个节点有多个分片的数据库集群添加新节点。" class="w-full my-4" >}}
|
||||
|
||||
In this model, only entire shards are moved between nodes, which is cheaper than splitting shards.
|
||||
The number of shards does not change, nor does the assignment of keys to shards. The only thing that
|
||||
changes is the assignment of shards to nodes. This change of assignment is not immediate—it takes
|
||||
some time to transfer a large amount of data over the network—so the old assignment of shards is
|
||||
used for any reads and writes that happen while the transfer is in progress.
|
||||
在这个模型中,只有整个分片在节点之间移动,这比分割分片更便宜。分片的数量不会改变,也不会改变键到分片的分配。唯一改变的是分片到节点的分配。这种分配的变化不是立即的——通过网络传输大量数据需要一些时间——因此在传输进行时,旧的分片分配用于任何发生的读写。
|
||||
|
||||
It’s common to choose the number of shards to be a number that is divisible by many factors, so that
|
||||
the dataset can be evenly split across various different numbers of nodes—not requiring the number
|
||||
of nodes to be a power of 2, for example [^4].
|
||||
You can even account for mismatched hardware in your cluster: by assigning more shards to nodes that
|
||||
are more powerful, you can make those nodes take a greater share of the load.
|
||||
选择分片数量为可被许多因子整除的数字是很常见的,这样数据集可以在各种不同数量的节点之间均匀分割——例如,不要求节点数必须是 2 的幂 [^4]。你甚至可以考虑集群中不匹配的硬件:通过为更强大的节点分配更多分片,你可以让这些节点承担更大份额的负载。
|
||||
|
||||
This approach to sharding is used in Citus (a sharding layer for PostgreSQL), Riak, Elasticsearch,
|
||||
and Couchbase, among others. It works well as long as you have a good estimate of how many shards
|
||||
you will need when you first create the database. You can then add or remove nodes easily, subject
|
||||
to the limitation that you can’t have more nodes than you have shards.
|
||||
这种分片方法被 Citus(PostgreSQL 的分片层)、Riak、Elasticsearch 和 Couchbase 等使用。只要你对首次创建数据库时需要多少分片有很好的估计,它就很有效。然后你可以轻松添加或删除节点,但受限于你不能拥有比分片更多的节点。
|
||||
|
||||
If you find the originally configured number of shards to be wrong—for example, if you have reached
|
||||
a scale where you need more nodes than you have shards—then an expensive resharding operation is
|
||||
required. It needs to split each shard and write it out to new files, using a lot of additional disk
|
||||
space in the process. Some systems don’t allow resharding while concurrently writing to the
|
||||
database, which makes it difficult to change the number of shards without downtime.
|
||||
如果你发现最初配置的分片数量是错误的——例如,如果你已经达到需要比分片更多节点的规模——那么需要进行昂贵的重新分片操作。它需要分割每个分片并将其写入新文件,在此过程中使用大量额外的磁盘空间。一些系统不允许在并发写入数据库时进行重新分片,这使得在没有停机时间的情况下更改分片数量变得困难。
|
||||
|
||||
Choosing the right number of shards is difficult if the total size of the dataset is highly variable
|
||||
(for example, if it starts small but may grow much larger over time). Since each shard contains a
|
||||
fixed fraction of the total data, the size of each shard grows proportionally to the total amount of
|
||||
data in the cluster. If shards are very large, rebalancing and recovery from node failures become
|
||||
expensive. But if shards are too small, they incur too much overhead. The best performance is
|
||||
achieved when the size of shards is “just right,” neither too big nor too small, which can be hard
|
||||
to achieve if the number of shards is fixed but the dataset size varies.
|
||||
如果数据集的总大小高度可变(例如,如果它开始很小但可能随时间增长得更大),选择正确的分片数量是困难的。由于每个分片包含总数据的固定部分,每个分片的大小与集群中的总数据量成比例增长。如果分片非常大,再平衡和从节点故障恢复会变得昂贵。但如果分片太小,它们会产生太多开销。当分片大小"恰到好处"时可以实现最佳性能,既不太大也不太小,如果分片数量固定但数据集大小变化,这可能很难实现。
|
||||
|
||||
#### 按哈希范围分片 {#sharding-by-hash-range}
|
||||
|
||||
If the required number of shards can’t be predicted in advance, it’s better to use a scheme in which
|
||||
the number of shards can adapt easily to the workload. The aforementioned key-range sharding scheme
|
||||
has this property, but it has a risk of hot spots when there are a lot of writes to nearby keys. One
|
||||
solution is to combine key-range sharding with a hash function so that each shard contains a range
|
||||
of *hash values* rather than a range of *keys*.
|
||||
如果无法提前预测所需的分片数量,最好使用一种方案,其中分片数量可以轻松适应工作负载。前面提到的键范围分片方案具有这个属性,但当有大量对相邻键的写入时,它有热点的风险。一种解决方案是将键范围分片与哈希函数结合,使每个分片包含 *哈希值* 的范围而不是 *键* 的范围。
|
||||
|
||||
[Figure 7-5](/en/ch7#fig_sharding_hash_range) shows an example using a 16-bit hash function that returns a number
|
||||
between 0 and 65,535 = 216 − 1 (in reality, the hash is usually 32 bits or more).
|
||||
Even if the input keys are very similar (e.g., consecutive timestamps), their hashes are uniformly
|
||||
distributed across that range. We can then assign a range of hash values to each shard: for example,
|
||||
values between 0 and 16,383 to shard 0, values between 16,384 and 32,767 to shard 1, and so on.
|
||||
[图 7-5](/ch7#fig_sharding_hash_range) 显示了使用 16 位哈希函数的示例,该函数返回 0 到 65,535 = 2¹⁶ − 1 之间的数字(实际上,哈希通常是 32 位或更多)。即使输入键非常相似(例如,连续的时间戳),它们的哈希值也会在该范围内均匀分布。然后我们可以为每个分片分配一个哈希值范围:例如,值 0 到 16,383 分配给分片 0,值 16,384 到 32,767 分配给分片 1,依此类推。
|
||||
|
||||
{{< figure src="/fig/ddia_0705.png" id="fig_sharding_hash_range" caption="Figure 7-5. Assigning a contiguous range of hash values to each shard." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0705.png" id="fig_sharding_hash_range" caption="图 7-5. 为每个分片分配连续的哈希值范围。" class="w-full my-4" >}}
|
||||
|
||||
Like with key-range sharding, a shard in hash-range sharding can be split when it becomes too big or
|
||||
too heavily loaded. This is still an expensive operation, but it can happen as needed, so the number
|
||||
of shards adapts to the volume of data rather than being fixed in advance.
|
||||
与键范围分片一样,哈希范围分片中的分片在变得太大或负载太重时可以被分割。这仍然是一个昂贵的操作,但它可以根据需要发生,因此分片数量适应数据量而不是预先固定。
|
||||
|
||||
The downside compared to key-range sharding is that range queries over the partition key are not
|
||||
efficient, as keys in the range are now scattered across all the shards. However, if keys consist of
|
||||
two or more columns, and the partition key is only the first of these columns, you can still perform
|
||||
efficient range queries over the second and later columns: as long as all records in the range query
|
||||
have the same partition key, they will be in the same shard.
|
||||
与键范围分片相比的缺点是,对分区键的范围查询效率不高,因为范围内的键现在分散在所有分片中。但是,如果键由两列或更多列组成,并且分区键只是这些列中的第一列,你仍然可以对第二列和后续列执行高效的范围查询:只要范围查询中的所有记录具有相同的分区键,它们就会在同一个分片中。
|
||||
|
||||
--------
|
||||
|
||||
> [!TIP] 数据仓库中的分区与范围查询
|
||||
> [!TIP] 数据仓库中的分区和范围查询
|
||||
|
||||
Data warehouses such as BigQuery, Snowflake, and Delta Lake support a similar indexing approach,
|
||||
though the terminology differs. In BigQuery, for example, the partition key determines which
|
||||
partition a record resides in while “cluster columns” determine how records are sorted within the
|
||||
partition. Snowflake assigns records to “micro-partitions” automatically, but allows users to define
|
||||
cluster keys for a table. Delta Lake supports both manual and automatic partition assignment, and
|
||||
supports cluster keys. Clustering data not only improves range scan performance, but can
|
||||
improve compression and filtering performance as well.
|
||||
数据仓库如 BigQuery、Snowflake 和 Delta Lake 支持类似的索引方法,尽管术语不同。例如,在 BigQuery 中,分区键决定记录驻留在哪个分区中,而"集群列"决定记录在分区内如何排序。Snowflake 自动将记录分配给"微分区",但允许用户为表定义集群键。Delta Lake 支持手动和自动分区分配,并支持集群键。聚集数据不仅可以提高范围扫描性能,还可以提高压缩和过滤性能。
|
||||
|
||||
--------
|
||||
|
||||
Hash-range sharding is used in YugabyteDB and DynamoDB [^17], and is an option in MongoDB.
|
||||
Cassandra and ScyllaDB use a variant of this approach that is illustrated in
|
||||
[Figure 7-6](/en/ch7#fig_sharding_cassandra): the space of hash values is split into a number of ranges proportional
|
||||
to the number of nodes (3 ranges per node in [Figure 7-6](/en/ch7#fig_sharding_cassandra), but actual numbers are 8
|
||||
per node in Cassandra by default, and 256 per node in ScyllaDB), with random boundaries between
|
||||
those ranges. This means some ranges are bigger than others, but by having multiple ranges per node
|
||||
those imbalances tend to even out [^15] [^18].
|
||||
哈希范围分片被 YugabyteDB 和 DynamoDB 使用 [^17],并且是 MongoDB 中的一个选项。Cassandra 和 ScyllaDB 使用这种方法的一个变体,如 [图 7-6](/ch7#fig_sharding_cassandra) 所示:哈希值空间被分割成与节点数成比例的范围数([图 7-6](/ch7#fig_sharding_cassandra) 中每个节点 3 个范围,但实际数字在 Cassandra 中默认为每个节点 8 个,在 ScyllaDB 中为每个节点 256 个),这些范围之间有随机边界。这意味着某些范围比其他范围大,但通过每个节点有多个范围,这些不平衡倾向于平均化 [^15] [^18]。
|
||||
|
||||
{{< figure src="/fig/ddia_0706.png" id="fig_sharding_cassandra" caption="Figure 7-6. Cassandra and ScyllaDB split the range of possible hash values (here 0–1023) into contiguous ranges with random boundaries, and assign several ranges to each node." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0706.png" id="fig_sharding_cassandra" caption="图 7-6. Cassandra 和 ScyllaDB 将可能的哈希值范围(这里是 0-1023)分割成具有随机边界的连续范围,并为每个节点分配多个范围。" class="w-full my-4" >}}
|
||||
|
||||
When nodes are added or removed, range boundaries are added and removed, and shards are split or
|
||||
merged accordingly [^19].
|
||||
In the example of [Figure 7-6](/en/ch7#fig_sharding_cassandra), when node 3 is added, node 1
|
||||
transfers parts of two of its ranges to node 3, and node 2 transfers part of one of its ranges to
|
||||
node 3. This has the effect of giving the new node an approximately fair share of the dataset,
|
||||
without transferring more data than necessary from one node to another.
|
||||
当添加或删除节点时,会添加和删除范围边界,并相应地分割或合并分片 [^19]。在 [图 7-6](/ch7#fig_sharding_cassandra) 的示例中,当添加节点 3 时,节点 1 将其两个范围的部分转移到节点 3,节点 2 将其一个范围的部分转移到节点 3。这样做的效果是给新节点一个大致公平的数据集份额,而不会在节点之间传输超过必要的数据。
|
||||
|
||||
#### 一致性哈希 {#sec_sharding_consistent_hashing}
|
||||
|
||||
A *consistent hashing* algorithm is a hash function that maps keys to a specified number of shards
|
||||
in a way that satisfies two properties:
|
||||
*一致性哈希* 算法是一种哈希函数,它以满足两个属性的方式将键映射到指定数量的分片:
|
||||
|
||||
1. the number of keys mapped to each shard is roughly equal, and
|
||||
2. when the number of shards changes, as few keys as possible are moved from one shard to another.
|
||||
1. 映射到每个分片的键数大致相等,并且
|
||||
2. 当分片数量变化时,尽可能少的键从一个分片移动到另一个分片。
|
||||
|
||||
Note that *consistent* here has nothing to do with replica consistency (see [Chapter 6](/en/ch6#ch_replication)) or
|
||||
ACID consistency (see [Chapter 8](/en/ch8#ch_transactions)), but rather describes the tendency of a key to stay in
|
||||
the same shard as much as possible.
|
||||
注意这里的 *一致性* 与副本一致性(见 [第 6 章](/ch6#ch_replication))或 ACID 一致性(见 [第 8 章](/ch8#ch_transactions))无关,而是描述了键尽可能保持在同一个分片中的倾向。
|
||||
|
||||
The sharding algorithm used by Cassandra and ScyllaDB is similar to the original definition of consistent hashing [^20],
|
||||
but several other consistent hashing algorithms have also been proposed [^21], such as *highest random weight*, also known as *rendezvous hashing* [^22],
|
||||
and *jump consistent hash* [^23].
|
||||
With Cassandra’s algorithm, if one node is added, a small number of existing shards are split into
|
||||
sub-ranges; on the other hand, with rendezvous and jump consistent hashes, the new node is assigned
|
||||
individual keys that were previously scattered across all of the other nodes. Which one is
|
||||
preferable depends on the application.
|
||||
Cassandra 和 ScyllaDB 使用的分片算法类似于一致性哈希的原始定义 [^20],但也提出了其他几种一致性哈希算法 [^21],如 *最高随机权重*,也称为 *会合哈希* [^22],以及 *跳跃一致性哈希* [^23]。使用 Cassandra 的算法,如果添加一个节点,少量现有分片会被分割成子范围;另一方面,使用会合和跳跃一致性哈希,新节点被分配之前分散在所有其他节点中的单个键。哪种更可取取决于应用程序。
|
||||
|
||||
### 倾斜的工作负载与缓解热点 {#sec_sharding_skew}
|
||||
|
||||
Consistent hashing ensures that keys are uniformly distributed across nodes, but that doesn’t mean
|
||||
that the actual load is uniformly distributed. If the workload is highly skewed—that is, the amount
|
||||
of data under some partition keys is much greater than other keys, or if the rate of requests to
|
||||
some keys is much higher than to others—you can still end up with some servers being overloaded
|
||||
while others sit almost idle.
|
||||
一致性哈希确保键在节点间均匀分布,但这并不意味着实际负载是均匀分布的。如果工作负载高度倾斜——即某些分区键下的数据量远大于其他键,或者对某些键的请求率远高于其他键——你仍然可能最终导致某些服务器过载,而其他服务器几乎处于空闲状态。
|
||||
|
||||
For example, on a social media site, a celebrity user with millions of followers may cause a storm
|
||||
of activity when they do something [^24].
|
||||
This event can result in a large volume of reads and writes to the same key (where the partition key
|
||||
is perhaps the user ID of the celebrity, or the ID of the action that people are commenting on).
|
||||
例如,在社交媒体网站上,拥有数百万粉丝的名人用户在做某事时可能会引起活动风暴 [^24]。这个事件可能导致对同一个键的大量读写(其中分区键可能是名人的用户 ID,或者人们正在评论的动作的 ID)。
|
||||
|
||||
In such situations, a more flexible sharding policy is required [^25] [^26].
|
||||
A system that defines shards based on ranges of keys (or ranges of hashes) makes it possible to put
|
||||
an individual hot key in a shard by its own, and perhaps even assigning it a dedicated machine [^27].
|
||||
在这种情况下,需要更灵活的分片策略 [^25] [^26]。基于键范围(或哈希范围)定义分片的系统使得可以将单个热键放在自己的分片中,甚至可能为其分配专用机器 [^27]。
|
||||
|
||||
It’s also possible to compensate for skew at the application level. For example, if one key is known
|
||||
to be very hot, a simple technique is to add a random number to the beginning or end of the key.
|
||||
Just a two-digit decimal random number would split the writes to the key evenly across 100 different
|
||||
keys, allowing those keys to be distributed to different shards.
|
||||
也可以在应用程序级别补偿倾斜。例如,如果已知一个键非常热,一个简单的技术是在键的开头或结尾添加一个随机数。仅仅一个两位数的十进制随机数就会将对该键的写入均匀分布在 100 个不同的键上,允许这些键分布到不同的分片。
|
||||
|
||||
However, having split the writes across different keys, any reads now have to do additional work, as
|
||||
they have to read the data from all 100 keys and combine it. The volume of reads to each shard of
|
||||
the hot key is not reduced; only the write load is split. This technique also requires additional
|
||||
bookkeeping: it only makes sense to append the random number for the small number of hot keys; for
|
||||
the vast majority of keys with low write throughput this would be unnecessary overhead. Thus, you
|
||||
also need some way of keeping track of which keys are being split, and a process for converting a
|
||||
regular key into a specially-managed hot key.
|
||||
然而,将写入分散到不同的键之后,任何读取现在都必须做额外的工作,因为它们必须从所有 100 个键读取数据并将其组合。对热键每个分片的读取量没有减少;只有写入负载被分割。这种技术还需要额外的记账:只对少数热键附加随机数是有意义的;对于写入吞吐量低的绝大多数键,这将是不必要的开销。因此,你还需要某种方法来跟踪哪些键正在被分割,以及将常规键转换为特殊管理的热键的过程。
|
||||
|
||||
The problem is further compounded by change of load over time: for example, a particular social
|
||||
media post that has gone viral may experience high load for a couple of days, but thereafter it’s
|
||||
likely to calm down again. Moreover, some keys may be hot for writes while others are hot for reads,
|
||||
necessitating different strategies for handling them.
|
||||
问题因负载随时间变化而进一步复杂化:例如,一个已经病毒式传播的特定社交媒体帖子可能会在几天内经历高负载,但之后可能会再次平静下来。此外,某些键可能对写入很热,而其他键对读取很热,需要不同的策略来处理它们。
|
||||
|
||||
Some systems (especially cloud services designed for large scale) have automated approaches for
|
||||
dealing with hot shards; for example, Amazon calls it *heat management* [^28] or *adaptive capacity* [^17].
|
||||
The details of how these systems work go beyond the scope of this book.
|
||||
一些系统(特别是为大规模设计的云服务)有自动处理热分片的方法;例如,Amazon 称之为 *热管理* [^28] 或 *自适应容量* [^17]。这些系统如何工作的细节超出了本书的范围。
|
||||
|
||||
### 运维:自动/手动再均衡 {#sec_sharding_operations}
|
||||
|
||||
There is one important question with regard to rebalancing that we have glossed over: does the
|
||||
splitting of shards and rebalancing happen automatically or manually?
|
||||
关于再平衡有一个我们已经忽略的重要问题:分片的分割和再平衡是自动发生还是手动发生?
|
||||
|
||||
Some systems automatically decide when to split shards and when to move them from one node to
|
||||
another, without any human interaction, while others leave sharding to be explicitly configured by
|
||||
an administrator. There is also a middle ground: for example, Couchbase and Riak generate a
|
||||
suggested shard assignment automatically, but require an administrator to commit it before it takes effect.
|
||||
一些系统自动决定何时分割分片以及何时将它们从一个节点移动到另一个节点,无需任何人工交互,而其他系统则让分片由管理员明确配置。还有一个中间地带:例如,Couchbase 和 Riak 自动生成建议的分片分配,但需要管理员提交才能生效。
|
||||
|
||||
Fully automated rebalancing can be convenient, because there is less operational work to do for
|
||||
normal maintenance, and such systems can even auto-scale to adapt to changes in workload. Cloud
|
||||
databases such as DynamoDB are promoted as being able to automatically add and remove shards to
|
||||
adapt to big increases or decreases of load within a matter of minutes [^17] [^29].
|
||||
完全自动的再平衡可能很方便,因为正常维护的操作工作较少,这样的系统甚至可以自动扩展以适应工作负载的变化。云数据库如 DynamoDB 被宣传为能够在几分钟内自动添加和删除分片以适应负载的大幅增加或减少 [^17] [^29]。
|
||||
|
||||
However, automatic shard management can also be unpredictable. Rebalancing is an expensive
|
||||
operation, because it requires rerouting requests and moving a large amount of data from one node to
|
||||
another. If it is not done carefully, this process can overload the network or the nodes, and it
|
||||
might harm the performance of other requests. The system must continue processing writes while the
|
||||
rebalancing is in progress; if a system is near its maximum write throughput, the shard-splitting
|
||||
process might not even be able to keep up with the rate of incoming writes [^29].
|
||||
然而,自动分片管理也可能是不可预测的。再平衡是一项昂贵的操作,因为它需要重新路由请求并将大量数据从一个节点移动到另一个节点。如果操作不当,这个过程可能会使网络或节点过载,并可能损害其他请求的性能。系统必须在再平衡进行时继续处理写入;如果系统接近其最大写入吞吐量,分片分割过程甚至可能无法跟上传入写入的速率 [^29]。
|
||||
|
||||
Such automation can be dangerous in combination with automatic failure detection. For example, say
|
||||
one node is overloaded and is temporarily slow to respond to requests. The other nodes conclude that
|
||||
the overloaded node is dead, and automatically rebalance the cluster to move load away from it. This
|
||||
puts additional load on other nodes and the network, making the situation worse. There is a risk of
|
||||
causing a cascading failure where other nodes become overloaded and are also falsely suspected of being down.
|
||||
这种自动化与自动故障检测结合可能很危险。例如,假设一个节点过载并暂时响应请求缓慢。其他节点得出结论,过载的节点已死,并自动重新平衡集群以将负载从它移开。这会对其他节点和网络施加额外负载,使情况变得更糟。存在导致级联故障的风险,其中其他节点变得过载并也被错误地怀疑已关闭。
|
||||
|
||||
For that reason, it can be a good thing to have a human in the loop for rebalancing. It’s slower
|
||||
than a fully automatic process, but it can help prevent operational surprises.
|
||||
出于这个原因,在再平衡过程中有人参与可能是件好事。它比完全自动的过程慢,但它可以帮助防止操作意外。
|
||||
|
||||
|
||||
|
||||
## 请求路由 {#sec_sharding_routing}
|
||||
|
||||
We have discussed how to shard a dataset across multiple nodes, and how to rebalance those shards as
|
||||
nodes are added or removed. Now let’s move on to the question: if you want to read or write a
|
||||
particular key, how do you know which node—i.e., which IP address and port number—you need to
|
||||
connect to?
|
||||
我们已经讨论了如何将数据集分片到多个节点上,以及如何在添加或删除节点时重新平衡这些分片。现在让我们继续讨论这个问题:如果你想读取或写入特定的键,你如何知道需要连接到哪个节点——即哪个 IP 地址和端口号?
|
||||
|
||||
We call this problem *request routing*, and it’s very similar to *service discovery*, which we
|
||||
previously discussed in [“Load balancers, service discovery, and service meshes”](/en/ch5#sec_encoding_service_discovery). The biggest difference between the two
|
||||
is that with services running application code, each instance is usually stateless, and a load
|
||||
balancer can send a request to any of the instances. With sharded databases, a request for a key can
|
||||
only be handled by a node that is a replica for the shard containing that key.
|
||||
我们称这个问题为 *请求路由*,它与 *服务发现* 非常相似,我们之前在 ["负载均衡器、服务发现和服务网格"](/ch5#sec_encoding_service_discovery) 中讨论过。两者之间最大的区别是,对于运行应用程序代码的服务,每个实例通常是无状态的,负载均衡器可以将请求发送到任何实例。对于分片数据库,对键的请求只能由包含该键的分片的副本节点处理。
|
||||
|
||||
This means that request routing has to be aware of the assignment from keys to shards, and from
|
||||
shards to nodes. On a high level, there are a few different approaches to this problem
|
||||
(illustrated in [Figure 7-7](/en/ch7#fig_sharding_routing)):
|
||||
这意味着请求路由必须知道键到分片的分配,以及分片到节点的分配。在高层次上,这个问题有几种不同的方法(在 [图 7-7](/ch7#fig_sharding_routing) 中说明):
|
||||
|
||||
1. Allow clients to contact any node (e.g., via a round-robin load balancer). If that node
|
||||
coincidentally owns the shard to which the request applies, it can handle the request directly;
|
||||
otherwise, it forwards the request to the appropriate node, receives the reply, and passes the
|
||||
reply along to the client.
|
||||
2. Send all requests from clients to a routing tier first, which determines the node that should
|
||||
handle each request and forwards it accordingly. This routing tier does not itself handle any
|
||||
requests; it only acts as a shard-aware load balancer.
|
||||
3. Require that clients be aware of the sharding and the assignment of shards to nodes. In this
|
||||
case, a client can connect directly to the appropriate node, without any intermediary.
|
||||
1. 允许客户端连接任何节点(例如,通过循环负载均衡器)。如果该节点恰好拥有请求适用的分片,它可以直接处理请求;否则,它将请求转发到适当的节点,接收回复,并将回复传递给客户端。
|
||||
2. 首先将客户端的所有请求发送到路由层,该层确定应该处理每个请求的节点并相应地转发它。这个路由层本身不处理任何请求;它只充当分片感知的负载均衡器。
|
||||
3. 要求客户端知道分片和分片到节点的分配。在这种情况下,客户端可以直接连接到适当的节点,而无需任何中介。
|
||||
|
||||
{{< figure src="/fig/ddia_0707.png" id="fig_sharding_routing" caption="Figure 7-7. Three different ways of routing a request to the right node." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0707.png" id="fig_sharding_routing" caption="图 7-7. 将请求路由到正确节点的三种不同方式。" class="w-full my-4" >}}
|
||||
|
||||
In all cases, there are some key problems:
|
||||
在所有情况下,都有一些关键问题:
|
||||
|
||||
* Who decides which shard should live on which node? It’s simplest to have a single coordinator
|
||||
making that decision, but in that case how do you make it fault-tolerant in case the node running
|
||||
the coordinator goes down? And if the coordinator role can failover to another node, how do you
|
||||
prevent a split-brain situation (see [“Handling Node Outages”](/en/ch6#sec_replication_failover)) where two different
|
||||
coordinators make contradictory shard assignments?
|
||||
* How does the component performing the routing (which may be one of the nodes, or the routing tier,
|
||||
or the client) learn about changes in the assignment of shards to nodes?
|
||||
* While a shard is being moved from one node to another, there is a cutover period during which the
|
||||
new node has taken over, but requests to the old node may still be in flight. How do you handle
|
||||
those?
|
||||
* 谁决定哪个分片应该存在于哪个节点上?最简单的是有一个单一的协调器做出该决定,但在这种情况下,如果运行协调器的节点出现故障,如何使其容错?如果协调器角色可以故障转移到另一个节点,如何防止脑裂情况(见 ["处理节点中断"](/ch6#sec_replication_failover)),其中两个不同的协调器做出相互矛盾的分片分配?
|
||||
* 执行路由的组件(可能是节点之一、路由层或客户端)如何了解分片到节点分配的变化?
|
||||
* 当分片从一个节点移动到另一个节点时,有一个切换期,在此期间新节点已接管,但对旧节点的请求可能仍在传输中。如何处理这些?
|
||||
|
||||
Many distributed data systems rely on a separate coordination service such as ZooKeeper or etcd to
|
||||
keep track of shard assignments, as illustrated in [Figure 7-8](/en/ch7#fig_sharding_zookeeper). They use consensus
|
||||
algorithms (see [Chapter 10](/en/ch10#ch_consistency)) to provide fault tolerance and protection against split-brain.
|
||||
Each node registers itself in ZooKeeper, and ZooKeeper maintains the authoritative mapping of shards
|
||||
to nodes. Other actors, such as the routing tier or the sharding-aware client, can subscribe to this
|
||||
information in ZooKeeper. Whenever a shard changes ownership, or a node is added or removed,
|
||||
ZooKeeper notifies the routing tier so that it can keep its routing information up to date.
|
||||
许多分布式数据系统依赖于单独的协调服务(如 ZooKeeper 或 etcd)来跟踪分片分配,如 [图 7-8](/ch7#fig_sharding_zookeeper) 所示。它们使用共识算法(见 [第 10 章](/ch10#ch_consistency))来提供容错和防止脑裂。每个节点在 ZooKeeper 中注册自己,ZooKeeper 维护分片到节点的权威映射。其他参与者,如路由层或分片感知客户端,可以在 ZooKeeper 中订阅此信息。每当分片所有权发生变化,或者添加或删除节点时,ZooKeeper 都会通知路由层,以便它可以保持其路由信息最新。
|
||||
|
||||
{{< figure src="/fig/ddia_0708.png" id="fig_sharding_zookeeper" caption="Figure 7-8. Using ZooKeeper to keep track of assignment of shards to nodes." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0708.png" id="fig_sharding_zookeeper" caption="图 7-8. 使用 ZooKeeper 跟踪分片到节点的分配。" class="w-full my-4" >}}
|
||||
|
||||
For example, HBase and SolrCloud use ZooKeeper to manage shard assignment, and Kubernetes uses etcd
|
||||
to keep track of which service instance is running where. MongoDB has a similar architecture, but it
|
||||
relies on its own *config server* implementation and *mongos* daemons as the routing tier. Kafka,
|
||||
YugabyteDB, and TiDB use built-in implementations of the Raft consensus protocol to perform this
|
||||
coordination function.
|
||||
例如,HBase 和 SolrCloud 使用 ZooKeeper 管理分片分配,Kubernetes 使用 etcd 跟踪哪个服务实例在哪里运行。MongoDB 有类似的架构,但它依赖于自己的 *配置服务器* 实现和 *mongos* 守护进程作为路由层。Kafka、YugabyteDB 和 TiDB 使用内置的 Raft 共识协议实现来执行此协调功能。
|
||||
|
||||
Cassandra, ScyllaDB, and Riak take a different approach: they use a *gossip protocol* among the
|
||||
nodes to disseminate any changes in cluster state. This provides much weaker consistency than a
|
||||
consensus protocol; it is possible to have split brain, in which different parts of the cluster have
|
||||
different node assignments for the same shard. Leaderless databases can tolerate this because they
|
||||
generally make weak consistency guarantees anyway (see [“Limitations of Quorum Consistency”](/en/ch6#sec_replication_quorum_limitations)).
|
||||
Cassandra、ScyllaDB 和 Riak 采用不同的方法:它们在节点之间使用 *流言协议* 来传播集群状态的任何变化。这提供了比共识协议弱得多的一致性;可能会出现脑裂,其中集群的不同部分对同一分片有不同的节点分配。无主数据库可以容忍这一点,因为它们通常提供弱一致性保证(见 ["仲裁一致性的限制"](/ch6#sec_replication_quorum_limitations))。
|
||||
|
||||
When using a routing tier or when sending requests to a random node, clients still need to find the
|
||||
IP addresses to connect to. These are not as fast-changing as the assignment of shards to nodes,
|
||||
so it is often sufficient to use DNS for this purpose.
|
||||
当使用路由层或向随机节点发送请求时,客户端仍然需要找到要连接的 IP 地址。这些不像分片到节点的分配那样快速变化,因此通常使用 DNS 就足够了。
|
||||
|
||||
This discussion of request routing has focused on finding the shard for an individual key, which is
|
||||
most relevant for sharded OLTP databases. Analytic databases often use sharding as well, but they
|
||||
typically have a very different kind of query execution: rather than executing in a single shard, a
|
||||
query typically needs to aggregate and join data from many different shards in parallel. We will
|
||||
discuss techniques for such parallel query execution in [Link to Come].
|
||||
这个关于请求路由的讨论集中在查找单个键的分片,这对于分片 OLTP 数据库最相关。分析数据库通常也使用分片,但它们通常有非常不同类型的查询执行:查询通常需要并行聚合和连接来自许多不同分片的数据,而不是在单个分片中执行。我们将在 [链接待定] 中讨论这种并行查询执行的技术。
|
||||
|
||||
## 分片与二级索引 {#sec_sharding_secondary_indexes}
|
||||
|
||||
The sharding schemes we have discussed so far rely on the client knowing the partition key for any
|
||||
record it wants to access. This is most easily done in a key-value data model, where the partition
|
||||
key is the first part of the primary key (or the entire primary key), and so we can use the
|
||||
partition key to determine the shard, and thus route reads and writes to the node that is
|
||||
responsible for that key.
|
||||
到目前为止,我们讨论的分片方案依赖于客户端知道它想要访问的任何记录的分区键。这在键值数据模型中最容易做到,其中分区键是主键的第一部分(或整个主键),因此我们可以使用分区键来确定分片,从而将读写路由到负责该键的节点。
|
||||
|
||||
The situation becomes more complicated if secondary indexes are involved (see also
|
||||
[“Multi-Column and Secondary Indexes”](/en/ch4#sec_storage_index_multicolumn)). A secondary index usually doesn’t identify a record uniquely but
|
||||
rather is a way of searching for occurrences of a particular value: find all actions by user `123`,
|
||||
find all articles containing the word `hogwash`, find all cars whose color is `red`, and so on.
|
||||
如果涉及二级索引,情况会变得更加复杂(另见 ["多列和二级索引"](/ch4#sec_storage_index_multicolumn))。二级索引通常不唯一地标识记录,而是一种搜索特定值出现的方法:查找用户 `123` 的所有操作、查找包含单词 `hogwash` 的所有文章、查找颜色为 `red` 的所有汽车等。
|
||||
|
||||
Key-value stores often don’t have secondary indexes, but they are the bread and butter of relational
|
||||
databases, they are common in document databases too, and they are the *raison d’être* of full-text
|
||||
search engines such as Solr and Elasticsearch. The problem with secondary indexes is that they don’t
|
||||
map neatly to shards. There are two main approaches to sharding a database with secondary indexes:
|
||||
local and global indexes.
|
||||
键值存储通常没有二级索引,但它们是关系数据库的基础,在文档数据库中也很常见,它们是 Solr 和 Elasticsearch 等搜索引擎的 *存在理由*。二级索引的问题是它们不能整齐地映射到分片。有两种主要方法来使用二级索引对数据库进行分片:本地索引和全局索引。
|
||||
|
||||
### 本地二级索引 {#id166}
|
||||
|
||||
For example, imagine you are operating a website for selling used cars (illustrated in
|
||||
[Figure 7-9](/en/ch7#fig_sharding_local_secondary)). Each listing has a unique ID, and you use that ID as partition
|
||||
key for sharding (for example, IDs 0 to 499 in shard 0, IDs 500 to 999 in shard 1, etc.).
|
||||
例如,假设你正在运营一个出售二手车的网站(如 [图 7-9](/ch7#fig_sharding_local_secondary) 所示)。每个列表都有一个唯一的 ID——称之为文档 ID——你使用该 ID 作为分区键对数据库进行分片(例如,ID 0 到 499 在分片 0 中,ID 500 到 999 在分片 1 中,等等)。
|
||||
|
||||
If you want to let users search for cars, allowing them to filter by color and by make, you need a
|
||||
secondary index on `color` and `make` (in a document database these would be fields; in a relational
|
||||
database they would be columns). If you have declared the index, the database can perform the
|
||||
indexing automatically. For example, whenever a red car is added to the database, the database shard
|
||||
automatically adds its ID to the list of IDs for the index entry `color:red`. As discussed in
|
||||
[Chapter 4](/en/ch4#ch_storage), that list of IDs is also called a *postings list*.
|
||||
如果你想让用户搜索汽车,允许他们按颜色和制造商过滤,你需要在 `color` 和 `make` 上建立二级索引(在文档数据库中这些是字段;在关系数据库中这些是列)。如果你已声明索引,数据库可以自动执行索引。例如,每当将红色汽车添加到数据库时,数据库分片会自动将其 ID 添加到索引条目 `color:red` 的文档 ID 列表中。如 [第 4 章](/ch4#ch_storage) 中所讨论的,该 ID 列表也称为 *发布列表*。
|
||||
|
||||
{{< figure src="/fig/ddia_0709.png" id="fig_sharding_local_secondary" caption="Figure 7-9. Local secondary indexes: each shard indexes only the records within its own shard." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0709.png" id="fig_sharding_local_secondary" caption="图 7-9. 本地二级索引:每个分片只索引其自己分片内的记录。" class="w-full my-4" >}}
|
||||
|
||||
> [!WARN] WARNING
|
||||
> [!WARN] 警告
|
||||
|
||||
If your database only supports a key-value model, you might be tempted to implement a secondary
|
||||
index yourself by creating a mapping from values to IDs in application code. If you go down this
|
||||
route, you need to take great care to ensure your indexes remain consistent with the underlying
|
||||
data. Race conditions and intermittent write failures (where some changes were saved but others
|
||||
weren’t) can very easily cause the data to go out of sync—see [“The need for multi-object transactions”](/en/ch8#sec_transactions_need).
|
||||
如果你的数据库只支持键值模型,你可能会尝试通过在应用程序代码中创建从值到文档 ID 的映射来自己实现二级索引。如果你走这条路,你需要格外小心,确保你的索引与底层数据保持一致。竞态条件和间歇性写入失败(其中某些更改已保存但其他更改未保存)很容易导致数据不同步——见 ["多对象事务的需求"](/ch8#sec_transactions_need)。
|
||||
|
||||
--------
|
||||
|
||||
In this indexing approach, each shard is completely separate: each shard maintains its own secondary
|
||||
indexes, covering only the records in that shard. It doesn’t care what data is stored in other
|
||||
shards. Whenever you write to the database—to add, remove, or update a records—you only need to
|
||||
deal with the shard that contains the record that you are writing. For that reason, this type of
|
||||
secondary index is known as a *local index*. In an information retrieval context it is also known as
|
||||
a *document-partitioned index* [^30].
|
||||
在这种索引方法中,每个分片是完全独立的:每个分片维护自己的二级索引,仅覆盖该分片中的文档。它不关心存储在其他分片中的数据。每当你需要写入数据库——添加、删除或更新记录——你只需要处理包含你正在写入的文档 ID 的分片。出于这个原因,这种类型的二级索引被称为 *本地索引*。在信息检索上下文中,它也被称为 *文档分区索引* [^30]。
|
||||
|
||||
When reading from a local secondary index, if you already know the partition key of the record
|
||||
you’re looking for, you can just perform the search on the appropriate shard. Moreover, if you only
|
||||
want *some* results, and you don’t need all, you can send the request to any shard.
|
||||
当从本地二级索引读取时,如果你已经知道你正在查找的记录的分区键,你可以只在适当的分片上执行搜索。此外,如果你只想要 *一些* 结果,而不需要全部,你可以将请求发送到任何分片。
|
||||
|
||||
However, if you want all the results and don’t know their partition key in advance, you need to send
|
||||
the query to all shards, and combine the results you get back, because the matching records might be
|
||||
scattered across all the shards. In [Figure 7-9](/en/ch7#fig_sharding_local_secondary), red cars appear in both shard
|
||||
0 and shard 1.
|
||||
但是,如果你想要所有结果并且事先不知道它们的分区键,你需要将查询发送到所有分片,并组合你收到的结果,因为匹配的记录可能分散在所有分片中。在 [图 7-9](/ch7#fig_sharding_local_secondary) 中,红色汽车出现在分片 0 和分片 1 中。
|
||||
|
||||
This approach to querying a sharded database can make read queries on secondary indexes quite
|
||||
expensive. Even if you query the shards in parallel, it is prone to tail latency amplification (see
|
||||
[“Use of Response Time Metrics”](/en/ch2#sec_introduction_slo_sla)). It also limits the scalability of your application: adding more
|
||||
shards lets you store more data, but it doesn’t increase your query throughput if every shard has to
|
||||
process every query anyway.
|
||||
这种查询分片数据库的方法有时称为 *分散/聚集*,它可能使二级索引上的读取查询相当昂贵。即使并行查询分片,分散/聚集也容易导致尾部延迟放大(见 ["响应时间指标的使用"](/ch2#sec_introduction_slo_sla))。它还限制了应用程序的可扩展性:添加更多分片让你存储更多数据,但如果每个分片无论如何都必须处理每个查询,它不会增加你的查询吞吐量。
|
||||
|
||||
Nevertheless, local secondary indexes are widely used [^31]: for example, MongoDB, Riak, Cassandra [^32], Elasticsearch [^33],
|
||||
SolrCloud, and VoltDB [^34] all use local secondary indexes.
|
||||
尽管如此,本地二级索引被广泛使用 [^31]:例如,MongoDB、Riak、Cassandra [^32]、Elasticsearch [^33]、SolrCloud 和 VoltDB [^34] 都使用本地二级索引。
|
||||
|
||||
### 全局二级索引 {#id167}
|
||||
|
||||
Rather than each shard having its own, local secondary index, we can construct a *global index* that
|
||||
covers data in all shards. However, we can’t just store that index on one node, since it would
|
||||
likely become a bottleneck and defeat the purpose of sharding. A global index must also be sharded,
|
||||
but it can be sharded differently from the primary key index.
|
||||
我们可以构建一个覆盖所有分片数据的 *全局索引*,而不是每个分片有自己的本地二级索引。但是,我们不能只将该索引存储在一个节点上,因为它可能会成为瓶颈并违背分片的目的。全局索引也必须进行分片,但它可以以不同于主键索引的方式进行分片。
|
||||
|
||||
[Figure 7-10](/en/ch7#fig_sharding_global_secondary) illustrates what this could look like: the IDs of red cars from
|
||||
all shards appear under `color:red` in the index, but the index is sharded so that colors starting
|
||||
with the letters *a* to *r* appear in shard 0 and colors starting with *s* to *z* appear in shard 1.
|
||||
The index on the make of car is partitioned similarly (with the shard boundary being between *f* and *h*).
|
||||
[图 7-10](/ch7#fig_sharding_global_secondary) 说明了这可能是什么样子:来自所有分片的红色汽车的 ID 出现在索引的 `color:red` 下,但索引是分片的,以便以字母 *a* 到 *r* 开头的颜色出现在分片 0 中,以 *s* 到 *z* 开头的颜色出现在分片 1 中。汽车制造商的索引也类似地分区(分片边界在 *f* 和 *h* 之间)。
|
||||
|
||||
{{< figure src="/fig/ddia_0710.png" id="fig_sharding_global_secondary" caption="Figure 7-10. A global secondary index reflects data from all shards, and is itself sharded by the indexed value." class="w-full my-4" >}}
|
||||
{{< figure src="/fig/ddia_0710.png" id="fig_sharding_global_secondary" caption="图 7-10. 全局二级索引反映来自所有分片的数据,并且本身按索引值进行分片。" class="w-full my-4" >}}
|
||||
|
||||
This kind of index is also called *term-partitioned* [^30]:
|
||||
recall from [“Full-Text Search”](/en/ch4#sec_storage_full_text) that in full-text search, a *term* is a keyword in a text that
|
||||
you can search for. Here we generalise it to mean any value that you can search for in the secondary index.
|
||||
这种索引也称为 *基于词项分区* [^30]:回忆一下 ["全文搜索"](/ch4#sec_storage_full_text),在全文搜索中,*词项* 是你可以搜索的文本中的关键字。这里我们将其推广为指二级索引中你可以搜索的任何值。
|
||||
|
||||
The global index uses the term as partition key, so that when you’re looking for a particular term
|
||||
or value, you can figure out which shard you need to query. As before, a shard can contain a
|
||||
contiguous range of terms (as in [Figure 7-10](/en/ch7#fig_sharding_global_secondary)), or you can assign terms to
|
||||
shards based on a hash of the term.
|
||||
全局索引使用词项作为分区键,因此当你查找特定词项或值时,你可以找出需要查询哪个分片。和以前一样,分片可以包含连续的词项范围(如 [图 7-10](/ch7#fig_sharding_global_secondary)),或者你可以基于词项的哈希将词项分配给分片。
|
||||
|
||||
Global indexes have the advantage that a query with a single condition (such as *color = red*) only
|
||||
needs to read from a single shard to fetch the postings list. However, if you want to fetch records
|
||||
and not just IDs, you still have to read from all the shards that are responsible for those IDs.
|
||||
全局索引的优点是具有单个条件的查询(如 *color = red*)只需要从单个分片读取以获取发布列表。但是,如果你想获取记录而不仅仅是 ID,你仍然必须从负责这些 ID 的所有分片中读取。
|
||||
|
||||
If you have multiple search conditions or terms (e.g., searching for cars of a certain color and a
|
||||
certain make, or searching for multiple words occurring in the same text), it’s likely that those
|
||||
terms will be assigned to different shards. To compute the logical AND of the two conditions, the
|
||||
system needs to find all the IDs that occur in both of the postings lists. That’s no problem if the
|
||||
postings lists are short, but if they are long, it can be slow to send them over the network to
|
||||
compute their intersection [^30].
|
||||
如果你有多个搜索条件或词项(例如,搜索某种颜色和某种制造商的汽车,或搜索同一文本中出现的多个单词),很可能这些词项将被分配给不同的分片。要计算两个条件的逻辑 AND,系统需要找到两个发布列表中都出现的所有 ID。如果发布列表很短,这没问题,但如果它们很长,通过网络发送它们来计算它们的交集可能会很慢 [^30]。
|
||||
|
||||
Another challenge with global secondary indexes is that writes are more complicated than with local
|
||||
indexes, because writing a single record might affect multiple shards of the index (every term in
|
||||
the document might be on a different shard). This makes it harder to keep the secondary index in
|
||||
sync with the underlying data. One option is to use a distributed transaction to atomically update
|
||||
the shards storing the primary record and its secondary indexes (see [Chapter 8](/en/ch8#ch_transactions)).
|
||||
全局二级索引的另一个挑战是写入比本地索引更复杂,因为写入单个记录可能会影响索引的多个分片(文档中的每个词项可能在不同的分片或不同的节点上)。这使得二级索引与底层数据保持同步更加困难。一种选择是使用分布式事务来原子地更新存储主记录的分片及其二级索引(见 [第 8 章](/ch8#ch_transactions))。
|
||||
|
||||
Global secondary indexes are used by CockroachDB, TiDB, and YugabyteDB; DynamoDB supports both local
|
||||
and global secondary indexes. In the case of DynamoDB, writes are asynchronously reflected in global
|
||||
indexes, so reads from a global index may be stale (similarly to replication lag, as in [“Problems with Replication Lag”](/en/ch6#sec_replication_lag)).
|
||||
Nevertheless, global indexes are useful if read throughput is higher than write throughput, and if
|
||||
the postings lists are not too long.
|
||||
全局二级索引被 CockroachDB、TiDB 和 YugabyteDB 使用;DynamoDB 支持本地和全局二级索引。在 DynamoDB 的情况下,写入异步反映在全局索引中,因此从全局索引读取可能是陈旧的(类似于复制延迟,如 ["复制延迟的问题"](/ch6#sec_replication_lag))。尽管如此,如果读取吞吐量高于写入吞吐量,并且发布列表不太长,全局索引是有用的。
|
||||
|
||||
|
||||
## 总结 {#summary}
|
||||
|
||||
In this chapter we explored different ways of sharding a large dataset into smaller subsets.
|
||||
Sharding is necessary when you have so much data that storing and processing it on a single machine
|
||||
is no longer feasible.
|
||||
在本章中,我们探讨了将大型数据集分片为更小子集的不同方法。当你有如此多的数据以至于在单台机器上存储和处理它不再可行时,分片是必要的。
|
||||
|
||||
The goal of sharding is to spread the data and query load evenly across multiple machines, avoiding
|
||||
hot spots (nodes with disproportionately high load). This requires choosing a sharding scheme that
|
||||
is appropriate to your data, and rebalancing the shards when nodes are added to or removed from the cluster.
|
||||
分片的目标是在多台机器上均匀分布数据和查询负载,避免热点(负载不成比例高的节点)。这需要选择适合你的数据的分片方案,并在节点添加到集群或从集群中删除时重新平衡分片。
|
||||
|
||||
We discussed two main approaches to sharding:
|
||||
我们讨论了两种主要的分片方法:
|
||||
|
||||
* *Key range sharding*, where keys are sorted, and a shard owns all the keys from some minimum up to
|
||||
some maximum. Sorting has the advantage that efficient range queries are possible, but there is a
|
||||
risk of hot spots if the application often accesses keys that are close together in the sorted
|
||||
order.
|
||||
* *键范围分片*,其中键是有序的,分片拥有从某个最小值到某个最大值的所有键。排序的优点是可以进行高效的范围查询,但如果应用程序经常访问排序顺序中彼此接近的键,则存在热点风险。
|
||||
|
||||
In this approach, shards are typically rebalanced by splitting the range into two subranges when a
|
||||
shard gets too big.
|
||||
* *Hash sharding*, where a hash function is applied to each key, and a shard owns a range of hash
|
||||
values (or another consistent hashing algorithm may be used to map hashes to shards). This method
|
||||
destroys the ordering of keys, making range queries inefficient, but it may distribute load more
|
||||
evenly.
|
||||
在这种方法中,当分片变得太大时,通常通过将范围分成两个子范围来动态重新平衡分片。
|
||||
* *哈希分片*,其中对每个键应用哈希函数,分片拥有一个哈希值范围(或者可以使用另一种一致性哈希算法将哈希映射到分片)。这种方法破坏了键的顺序,使范围查询效率低下,但可能更均匀地分布负载。
|
||||
|
||||
When sharding by hash, it is common to create a fixed number of shards in advance, to assign several
|
||||
shards to each node, and to move entire shards from one node to another when nodes are added or
|
||||
removed. Splitting shards, like with key ranges, is also possible.
|
||||
当按哈希分片时,通常预先创建固定数量的分片,为每个节点分配多个分片,并在添加或删除节点时将整个分片从一个节点移动到另一个节点。像键范围一样分割分片也是可能的。
|
||||
|
||||
It is common to use the first part of the key as the partition key (i.e., to identify the shard),
|
||||
and to sort records within that shard by the rest of the key. That way you can still have efficient
|
||||
range queries among the records with the same partition key.
|
||||
通常使用键的第一部分作为分区键(即,识别分片),并在该分片内按键的其余部分对记录进行排序。这样,你仍然可以在具有相同分区键的记录之间进行高效的范围查询。
|
||||
|
||||
We also discussed the interaction between sharding and secondary indexes. A secondary index also
|
||||
needs to be sharded, and there are two methods:
|
||||
我们还讨论了分片和二级索引之间的交互。二级索引也需要进行分片,有两种方法:
|
||||
|
||||
* *Local secondary indexes*, where the secondary indexes are stored
|
||||
in the same shard as the primary key and value. This means that only a single shard needs to be
|
||||
updated on write, but a lookup of the secondary index requires reading from all shards.
|
||||
* *Global secondary indexes*, which are sharded separately based on
|
||||
the indexed values. An entry in the secondary index may refer to records from all shards of the
|
||||
primary key. When a record is written, several secondary index shards may need to be updated;
|
||||
however, a read of the postings list can be served from a single shard (fetching the actual
|
||||
records still requires reading from multiple shards).
|
||||
* *本地二级索引*,其中二级索引与主键和值存储在同一个分片中。这意味着写入时只需要更新一个分片,但二级索引的查找需要从所有分片读取。
|
||||
* *全局二级索引*,它们基于索引值单独分片。二级索引中的条目可能引用来自主键所有分片的记录。写入记录时,可能需要更新多个二级索引分片;但是,可以从单个分片提供发布列表的读取(获取实际记录仍需要从多个分片读取)。
|
||||
|
||||
Finally, we discussed techniques for routing queries to the appropriate shard, and how a
|
||||
coordination service is often used to keep track of the assigment of shards to nodes.
|
||||
最后,我们讨论了将查询路由到适当分片的技术,以及协调服务通常用于跟踪分片到节点的分配的方式。
|
||||
|
||||
By design, every shard operates mostly independently—that’s what allows a sharded database to scale
|
||||
to multiple machines. However, operations that need to write to several shards can be problematic:
|
||||
for example, what happens if the write to one shard succeeds, but another fails? We will address
|
||||
that question in the following chapters.
|
||||
按设计,每个分片主要独立运行——这就是允许分片数据库扩展到多台机器的原因。但是,需要写入多个分片的操作可能会有问题:例如,如果对一个分片的写入成功,但对另一个分片的写入失败,会发生什么?我们将在以下章节中解决该问题。
|
||||
|
||||
|
||||
|
||||
|
||||
### 参考
|
||||
### References
|
||||
|
||||
[^1]: Claire Giordano. [Understanding partitioning and sharding in Postgres and Citus](https://www.citusdata.com/blog/2023/08/04/understanding-partitioning-and-sharding-in-postgres-and-citus/). *citusdata.com*, August 2023. Archived at [perma.cc/8BTK-8959](https://perma.cc/8BTK-8959)
|
||||
[^2]: Brandur Leach. [Partitioning in Postgres, 2022 edition](https://brandur.org/fragments/postgres-partitioning-2022). *brandur.org*, October 2022. Archived at [perma.cc/Z5LE-6AKX](https://perma.cc/Z5LE-6AKX)
|
||||
|
2298
content/zh/ch8.md
2298
content/zh/ch8.md
File diff suppressed because it is too large
Load Diff
1663
content/zh/ch9.md
1663
content/zh/ch9.md
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user