Solution Architecture — A Practitioner's Course
A self-study course in solution architecture, built from public standards and literature: ISO/IEC/IEEE 42010, ISO/IEC 25010, the SEI's architecture body of work, TOGAF, and the pattern literature. Every framework here is traceable to a citable primary source, listed in References and further reading at the end.
Read it front to back once, then use the module sections as reference. Every module ends with exercises against a single fictional case study — Lumen Diagnostics — so the practice compounds instead of restarting each time. The case study is defined in the Case study appendix; read it before starting the Module 2 exercises.
How to use this course
| Phase | Modules | What you produce |
|---|---|---|
| Understand the business | 1, 2 | Drivers/goals/objectives, stakeholder registry, RACI, functional decomposition |
| Nail the requirements | 3 | ASR list, utility tree, tactics for top-3 quality attributes |
| Choose the shape | 4, 5 | Style/pattern selection, models and diagrams |
| Write it down | 6 | Software Architecture Document with 3+ views |
| Sell and plan it | 7 | WBS, estimate, resource plan, discovery plan |
| Design, review, govern | 8 | ADD iterations, ATAM review, governance model |
| Pick the technology | 9 | Deployment view, availability calculation, running costs |
| Capstone | GW | Full RFP response |
Rendering diagram…
Module 1 — Introduction to Solution Architecture
What architecture actually is
There is no unified definition. The course deliberately starts by comparing definitions from ISO/IEC/IEEE 42010, SEI and others, and asking two questions worth keeping for your whole career:
- Is software architecture a process or a product?
- Which definition is complete or right?
What an architecture description contains, at the level that matters:
| Included | Excluded as "unimportant detail" |
|---|---|
| Elements (VMs, web servers, load balancers, DBaaS) | API signature details |
| Element attributes (scaling, replication, CPU/memory/capacity, VM type/size/image) | Frameworks |
| Interfaces (protocols, APIs) | Internal implementation details |
| Database schemas |
Types of architecture
| Type | Focus | Note |
|---|---|---|
| Enterprise | Business–technology alignment; the right investments, evolution toward a future-state vision | More abstract |
| Solution | A solution to a business problem; business goals come first | More concrete |
| Technical / Software | Core technical architecture with a focus on good design | Deep in one or few technologies |
| Infrastructure | Servers, containers, deployment, CI/CD — effectively DevOps | In some organisations these are called System Architects; the "System Architecture" definition varies |
The three-axis mental model uses strategy focus, technology breadth and technology depth: a technical architect has depth in one or many technologies; an enterprise architect lives at the level of organisational strategy; a solution architect sits in the middle, balancing the two.
Solution architecture is, per Forrester, one of the key methods by which enterprise architecture delivers value to the organisation. Comparing solution and software architecture: solution architecture is more business-oriented and the architect's primary responsibility is to talk with the business and achieve their goals appropriately; a software architect can and should focus on software design.
Solution architect activities
RFP/RFI processing
- Translate business requirements into a technical solution
- Client calls and on-site presentations
- High-level architecture design, effort estimation
- Requirements gathering (business needs/strategy, functional, non-functional)
- Levelling applies here too: SA L1/2 for technical parts, SA L2/3 for addressing business needs
Discovery
- Clarify technical and business parts of the solution — technology choice, integrations, analysis of the customer's IT landscape
- Participate in on-site and off-site workshops
- SA is not BA: SA is about breadth and architectural approach/strategy; BA is about depth, clarifying and documenting details
- Typical outputs: design, efforts, timeline
Architecture review — a process where architectural decisions are evaluated as to how they enable or restrict the system in meeting its Architecturally Significant Requirements.
Architecture governance — the practice and orientation by which architectures are managed and controlled at an enterprise-wide level. Mostly an enterprise-architect activity, and a bit outside the solution architect's focus: consistency between sub-architectures, identifying re-usable components, architecture compliance across the enterprise.
Architecture context: the influence cycle
Architecture is not a one-way flow. Four forces shape it, and the resulting system then reshapes all four.
Rendering diagram…
How the system influences back:
- Stakeholder requirements for the next system — the customer can receive a system based on the same architecture more reliably, sooner and more economically than building from scratch, typically with fewer defects.
- The structure of the developing organisation — architecture prescribes the units of software that must be implemented or obtained and integrated; a software module often maps 1-to-1 onto an organisational unit.
- The business goals of the developing organisation — a successful system can establish a foothold in a market segment, and the organisation may adjust its goals to exploit its newfound expertise.
- The architect's experience — every project adds to the corporate and personal experience base.
On the input side: stakeholders each bring their own requirements and concerns; the technical environment grows constantly, and decisions get influenced by trends and buzzwords; the architect's own experience — the styles, patterns and platforms they have tried, good and bad — pushes them to apply prior knowledge to the current system.
Because it is impossible to achieve all things for all stakeholders at all times, finding a trade-off may be the key goal of a solution architect.
Structures and views
Three terms that must not be confused:
- Structure — the set of elements and their organisation (e.g. the module structure).
- View — a representation of a structure, documented per a template in a chosen notation, and used by some stakeholders.
- Viewpoint — where you are looking from: a set of conventions for constructing, interpreting, using and analysing one type of view. A viewpoint includes model kinds, viewpoint languages and notations, modelling methods and analytic techniques to frame a specific set of concerns. Examples: operational, systems, technical, logical, deployment, process, information.
Architects design structures. They document views of those structures. A view is what you see; a viewpoint is where you look from.
An architecture view in an AD expresses the architecture of the system of interest from the perspective of one or more stakeholders to address specific concerns, using the conventions established by its viewpoint. A view consists of one or more architecture models.
The original definitions come from ISO; other sources copy and explain or modify them. Do not spend excessive time on the distinction — understanding comes with experience.
The SEI categorisation of structures
| Category | Elements | Questions it answers |
|---|---|---|
| Module | Modules — units of implementation, assigned areas of functional responsibility. A code-based way of considering the system, with less emphasis on runtime manifestation | What is the primary functional responsibility of each module? What other elements is a module allowed to use? What does it actually use? What modules are related by generalization or specialization (inheritance)? |
| Component-and-connector | Runtime components (principal units of computation) and connectors (communication vehicles among components) | What are the major executing components and how do they interact? What are the major shared data stores? Which parts are replicated? How does data progress through the system? What can run in parallel? How can the structure change as it executes? |
| Allocation | The relationship between software elements and elements in one or more external environments in which the software is created and executed | What processor does each element execute on? In what files is each element stored during development, testing and build? What is the assignment of elements to development teams? |
Specific structures within them:
| Structure | Category | Relation | Purpose |
|---|---|---|---|
| Decomposition | Module | "is a submodule of" | Larger modules decomposed recursively until small enough to be easily understood. A common starting point for design as the architect enumerates what the units must do and assigns each to a module for later detailed design and implementation |
| Uses | Module | "uses" | Important but overlooked. Units are modules or, at finer grain, procedures or resources on module interfaces. One unit uses another if the correctness of the first requires the presence of a correct version (not a stub) of the second |
| Layered | Module | carefully controlled uses | When uses relations are controlled in a particular way, layers emerge — a layer being a coherent set of related functionality. In a strictly layered structure layer n may only use layer n−1; many variations and relaxations occur in practice. Layers are often designed as abstractions (virtual machines) hiding implementation specifics below, engendering portability |
| Client-server | C&C | protocols and messages | Components are clients and servers; connectors are the protocols and messages they share. Useful for separation of concerns (supporting modifiability), physical distribution, and load balancing (supporting runtime performance) |
| Deployment | Allocation | "allocated-to", "migrates-to" | How software is assigned to hardware-processing and communication elements. Elements are software (usually a process from a C&C view), hardware entities (processors) and communication pathways. Lets an engineer reason about performance, data integrity, availability and security; of particular interest in distributed or parallel systems |
| Implementation | Allocation | mapping to file structures | How software elements (usually modules) map to the file structures in development, integration or configuration-control environments. Critical for managing development activities and build processes |
| Work assignment | Allocation | responsibility | Assigns responsibility for implementing and integrating modules to development teams. Makes clear that deciding who does the work has architectural as well as management implications; the architect knows the expertise each team requires. On large multi-sourced distributed projects it is the means of calling out units of functional commonality and assigning them to a single team rather than having everyone who needs them implement them |
Conceptual / logical / physical
| Level | What it expresses |
|---|---|
| Conceptual | A set of relationships between factors believed to impact or lead to a target condition; theoretical entities, objects or conditions of a system and the relationships between them. Represents concepts and relationships, expressing the meaning of the terms and concepts domain experts use to discuss the problem, and finding the correct relationships between different concepts |
| Logical | Logical relationships between the resources, activities, outputs and outcomes of a programme, assessing the causal relationships between elements. Addresses the information system macroscopically by focusing on its main components, their interconnections and the flows exchanged, structuring them by group into larger-scale modules |
| Physical | Network capabilities, server specifications, hardware requirements and other information related to deploying the proposed system |
Architecture and Agile
Architecture exists in every project independent of the process or methodology used. To succeed in delivery and make customers happy, each project from mid-sized upward should have a Delivery Manager and a Solution Architect collaborating toward a common goal.
The myths, and the reality:
| Myth | Reality |
|---|---|
| Big up-front design | Each system should be designed and documented reasonably: analyse current needs and provide as much design as is required and enough to start the project or make it successful |
| Longer releases | Architecture design approaches are themselves iterative and incremental. Creating design is an incremental process — every day new requirements arrive or business goals change, and it is absolutely fine to update the design incrementally |
| Massive documentation | It is perfectly fine to have a small amount of documentation if it suffices for your concrete project. If Confluence pages with photos of your whiteboarding are enough, that is fine. There is no sense creating 100 pages of architecture documents never used after they are created |
| Architects are decision makers | Solution architects' decisions are based on stakeholder needs. The primary task is to identify and understand the business goal; all decisions — design, technology stack, tactics for achieving quality attributes — should be based on those goals |
| Decisions are hard to reverse | Evolutionary Architecture is an effective approach supporting incremental changes: organised around business capabilities, fine-grained, modular |
| Long-term vs incremental design | While creating design, do it incrementally and iteratively |
| Low visible value | In some cases there is no sense in big up-front design — concentrate on concrete business goals and high-priority business features instead |
Solution architect and delivery manager look at the same successful delivery from different angles — technical and delivery. From the client side both are regarded as part of the senior governance roles of the account, and clients expect the two to be synced up, aligned and going hand-in-hand.
Competency levels
| Level | Expectation |
|---|---|
| Early career | Designs small-to-medium solutions, often under the guidance of a more senior architect on large engagements. Contributes technical sections to proposals. Deep in one or two technology stacks and a domain or two. An experienced problem solver and a mature developer and lead |
| Mid career | Owns large solutions and leads proposal work — which is part management, part selling, and harder than either. Broader stack and domain coverage, and now needs working knowledge of enterprise architecture, because from this point the two disciplines start to overlap |
| Senior / principal | Leads the most demanding engagements. Solution and enterprise architecture in equal measure; capable of governance and senior technology-management roles on the customer side; works credibly with executive peers; understands the business strategy well enough to help execute it |
Requirements are generic plus practice-specific: a data and analytics practice (DW/BI/Big Data/DevOps), an enterprise technology practice (Java/.NET/integration/Agile), and a digital experience practice (commerce/CMS/mobile/front-end) will each add their own expectations on top of the generic ones.
Exercises — Module 1
No assignment; the module is orientation. Soft skills are trained implicitly during the practices and can be developed explicitly through dedicated training.
Module 2 — Business Architecture
Business architecture is "a blueprint of the enterprise that provides a common understanding of the organization and is used to align strategic objectives and tactical demands." It is the bridge between the enterprise business model and strategy on one side, and the business functionality of the enterprise on the other.
The module's teaching device is worth copying: participants are asked to analyse a client's business from a scenario before learning any of the terminology, timeboxed to 15–20 minutes. Then the same scenario is revisited at the end, so the difference in quality is felt rather than told.
Drivers, goals, objectives
Business driver — a resource, process or condition vital for the continued success and growth of a business. A company must identify its drivers and try to maximise those under its control; there are always outside drivers it cannot influence, such as economic conditions or trade relations between nations. Name a driver with a noun.
Four categories — everything in a business case must relate directly to proving one or more:
- Increase or protect revenue
- Reduce cost or increase efficiency
- Reduce risk
- Compliance
Examples of drivers: accelerate revenue recognition; reduce COGS/cost; improve business productivity (more goods from the same inputs); improve business effectiveness (product-to-market penetration); improve market competitiveness (share); enable new business; mitigate risk; improve planning and forecasting.
How to find drivers — root-cause analysis over the financial statements. Start from the statements and ask "what drives this line item?" repeatedly:
What drives revenue? → volume of products sold × average price. What drives volume? → the number of products and the number of salespeople. What drives salespeople? → the number and sizes of stores. What drives the number of stores? → this is a core business driver — an operational and capital decision, with nothing preceding it.
Repeat for each line item on each of the three financial statements, then determine which drivers are most important to focus on: those that impact the most areas of the business and have the largest effect on results.
Goals vs objectives: goals are general statements of desired achievement; objectives are the specific steps or actions taken to reach a goal. Both should be specific, measurable and SMART. Goals can involve profitability, growth, customer service. Express them with qualitative words — "increase", "improve", "easier".
Terminology varies: some companies use goals for the company as a whole, objectives for departments, and targets for individual employees.
Do not start out with what you have and then figure out what it can be used for. A far more successful approach is to start with what you want to accomplish, then determine what you have — and what you need — in order to accomplish it.
As an architect you must do the background research necessary to understand the goals; they are not always clearly explained in the case.
Rendering diagram…
Worked example — a university has greatly expanded its CS course and wants to automate grading of simple programming assignments:
| Element | Value |
|---|---|
| Driver | Be the CS leader in the country — the university has a record for the highest-performing CS graduates and wants to attract more students and protect its revenue and market |
| Goal 1 | Increase the number of highest-performing CS graduates → Objective: expand the CS course |
| Goal 2 | Improve grade-process efficiency → Objectives: decrease grade-process duration; decrease the cost of the grade process |
Goal 2 exists because goal 1 has a consequence: more students significantly increase the cost and duration of grading. Goals are strategic, set over months or years — attach possible metrics so achievement can be proven. The final picture should let you trace Drivers → Goals → Objectives, with each objective covered by some part of the solution.
Business value, capabilities, value streams
- Business value — the benefits a firm generates for its stakeholders, including long-term ability to create revenue, products, services, employment, quality of life and investment returns.
- Business capability — encapsulates what a business is doing right now and what it needs to be doing to meet current and future challenges. Capabilities define what a business does rather than how (which processes describe). "Recruit talented employees" is a capability necessary to a goal of having a competitive workforce; it says what is needed but leaves open whether there is an HR process from recruiting website to interviews to hiring administration, or whether everything is outsourced. Capabilities are the basic building blocks of a business, and the capability map in its entirety delivers a concise, non-redundant, business-centric view at its most basic level.
- Value stream — an artifact allowing a business to specify the value proposition derived by an external (customer) or internal stakeholder. It depicts the stakeholders initiating and involved, the stages creating specific value items, and the value proposition derived — an end-to-end collection of value-adding activities creating an overall result for a customer, stakeholder or end-user, using capabilities as steps. The value map shows how the organisation creates the value exchanged between itself and its stakeholders.
- Value proposition — an innovation, service or feature intended to make a company, product or service attractive. In a nutshell it explains how your product solves customers' problems or improves their situation, delivers specific quantified benefits, and tells why the customer should buy from you and not the competition.
- Strategy — the pattern or plan integrating an organisation's major goals, policies and action sequences into a cohesive whole. The balanced scorecard is a strategy performance management tool — a semi-standard structured report supported by design methods and automation tools.
- Information — the typical approach: extract information concepts from capabilities; identify capability-based relationships for information concepts; extract relationships from matching capabilities; define information concepts; identify their types; identify their use; validate the information map.
- Organisation — the organisation map provides visibility on the business, describing business units and communication approach. An organisation typically has one or more leaders making strategic decisions. One way to describe it is via capabilities and their virtual relationships; another is an organisational chart describing structure, departments, groups and teams hierarchically.
The value of a capability map lies mostly in analysing current vs desired levels of capability, and in uncovering capabilities the organisation already possesses but does not recognise or manage explicitly. Capabilities and capability levels in a target business architecture give high-level direction for change — this is the core of capability-based planning.
Stakeholders
There are always several stakeholders and all are important, as they define official and often personal requirements and interests that must be taken into consideration. Understanding the organisation and business context helps identify vendors, partners, HR, clients and everyone else who needs to be on the architect's radar.
Identification techniques:
| Technique | Use |
|---|---|
| Brainstorming | Produce the stakeholder list and identify roles and responsibilities |
| Interviews | Interact with specific stakeholders for more information about stakeholder groups |
| Workshops | Interact with groups of stakeholders |
| Mind mapping | Identify potential stakeholders and understand the relationships between them |
| Organisational modelling | Determine whether listed units or people have unique needs and interests; models describe roles and functions and the ways stakeholders interact, helping identify who will be affected by a change |
| Process modelling | Categorise stakeholders by the systems supporting their business processes |
| Stakeholder list, map or personas | Depict the relationship of stakeholders to the solution and to one another |
| Survey or questionnaire | Identify shared characteristics of a stakeholder group |
Definitions:
- Stakeholder groups — depending on classification, a stakeholder may belong to different groups: organisation/organisation unit, or power/influence/interest.
- Concerns — the issues, risks and constraints stakeholders have with the solution. This may include the use of the solution, perceptions of its value, and the impact it has on a stakeholder's ability to perform necessary functions.
- Stakeholder requirements — describe the needs of stakeholders that must be met to achieve the business requirements; they may serve as a bridge between business and solution requirements.
Stakeholder registry (worked example)
| Name | Role | Group | Concerns | Views |
|---|---|---|---|---|
| Vasya Pupkin | Student | User | Usability, Performance | User Guide |
| Albert Schmitt | Professor, SME | User | Usability, Performance | User Guide |
| Viktor Romanov | Admin | User | Usability, Performance, Security | Admin Guide |
| Dan Schmitt | Sponsor | Customer | Cost, Timeline | Conceptual diagram, Business Footprint diagram, Business motivation diagram |
| Chris Rock | LMS SME | Customer | Integrability, Performance, Availability, Security | Integration Data Flow Diagram, Context diagram, Components diagram |
| George Walter | Project Manager | Project Team | Product Quality, Risk Assessment, Cost, Staffing, Customer Satisfaction | TCQ, Project Plan, WBS |
| Andy Donald | Solution Architect | Project Team | Solution Architecture, Constraints, Requirements | Context diagram, Sequence diagram, Components diagram |
| Rada Kandola | IT Support | Project Team | Usability, Performance, Availability | Use-case diagram, Workflow diagram, User Guide |
| Ravi Kumar | Developer | Project Team | Scope, Resources, Project Plan | Sequence, Context, Components, Integration Data Flow, Use-case diagrams |
| Sachin Dave | Tester | Project Team | Scope, Resources, Project Plan | Components, Sequence, Use-case diagrams |
| Satty Kumar | DevOps | Project Team | Scope, Resources, Project Plan, CI/CD | Deployment Diagram |
The three groups to work through: Users of the system (concerned with usability and performance; a professor may double as SME); Customers — the sponsor who pays and is concerned with timeline and cost, plus integration SMEs, and very often CEO, CTO/CIO, CFO, enterprise architect, security department, marketing; and the Project Team who design, implement and support the solution, which may also include BAs, data scientists, security architects and system architects depending on the requirements.
Some stakeholders can be found in the case description, but most of them are hidden, and it is a real art to find all project stakeholders.
Power / interest prioritisation
| Low impact | High impact | |
|---|---|---|
| High power / influence | Keep satisfied — they have needs that should be met. Engage and consult with them while attempting to increase their level of interest in the change activity. Typically the Customers group, e.g. the Sponsor | Key players in the change effort — focus your effort and engage this group regularly. Typically most of the Project Team: PM, SA, Developer, DevOps, Tester |
| Low power / influence | Minimal effort — keep informed using general communications. Additional engagement may move them into the goodwill-ambassador quadrant, which can help gain support. E.g. Student and Admin | Goodwill ambassadors — supporters of and potential advocates for the change. Engage for their input and show interest in their needs. E.g. Professor, LMS SME, IT Support — SMEs and third parties needed for integration and support |
RACI
- Responsible — the person assigned to do the work
- Accountable — the person who makes the final decision and has ultimate ownership
- Consulted — must be consulted before a decision is made
- Informed — must be informed that a decision or action has been taken
The most complicated part is understanding the difference between Accountable and Responsible. The accountable person signs off the work, has the authority to make a decision, and is whose head rolls if it goes wrong. The responsible person is responsible for the execution of the activity. Accountability comes before responsibility, and one activity must be associated with a single accountable person only.
Example for a construction phase:
| Activity | Sponsor | Admin | Student | Professor | LMS SME | PM | SA | IT Support | Dev | Tester | DevOps |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Project Initiation | C | C | C | A/R | |||||||
| Architecture | I | C | A | R | C | C | C | ||||
| Project Planning | C | A | C | C | C | C | |||||
| Requirements | C | A | R | R | R | R | |||||
| Documentation | I | C | I | A | R | I | R | R | R | ||
| Development | I | A | C | I | R | R | R | ||||
| Integration | A | C | R | R | R | ||||||
| Stabilization | A | C | R | R | R | ||||||
| UAT | I | A | C | R | R | R | |||||
| Support | I | I | I | A | R | I | I | I |
In this case the PM is accountable for every stage — but that does not mean the PM is always accountable for everything. During earlier or later project phases there will most likely be another accountable person, for example from the customer side. A template can exist, but the project has its own RACI matrix tuned to the current project context, and there will be deviations on each project. SDLC and its underlying tasks are driven both by business conditions and the state of the existing enterprise; everything constantly evolves, so there will be deviations.
A richer real-world RACI covers areas of responsibility such as: resource/budget planning, position planning and assignment, release planning, release delivery, testing, test automation, requirements management, sprint planning, product roadmap, backend architecture, UI architecture, managing budget resources, managing organisational issues, risk management, user support, DevOps (CI/CD and environment support), performance testing, UI/UX architecture, and security on the project.
Requirements (BABOK classification)
| Type | Definition |
|---|---|
| Business requirements | Higher-level needs of the enterprise |
| Stakeholder requirements | The needs of stakeholders that must be met to achieve the business requirements |
| Solution requirements | Split into functional and non-functional |
| Transition requirements | Capabilities the solution must have and conditions it must meet to facilitate transition from the current state to the future state, but which are not needed once the change is complete. Differentiated from other types because they are temporary in nature. They address data conversion, training and business continuity |
Functional requirements — product features or functions developers must implement to enable users to accomplish their tasks, so they must be clear to both the development team and the stakeholders. They generally describe system behaviour under specific conditions:
- The system sends an approval request after the user enters personal information.
- A search feature allows a user to hunt among various invoices if they want to credit an issued invoice.
- The system sends a confirmation email when a new user account is created.
Non-functional requirements — not related to system functionality but defining how the system should perform:
- The website pages should load in 3 seconds with fewer than 5,000 simultaneous users.
- The system should be able to handle 20 million users without performance deterioration.
Note the terminology debate the course flags: some people dislike "non-functional" and use QA requirement or constraint instead, because some such requirements — performance, for instance — might be a very important "function".
Risks, assumptions, issues, dependencies
| Term | Meaning |
|---|---|
| Risk | Any specific event that might occur and thus have a negative impact on the project or programme. Each has an associated probability of occurrence and an impact if it materialises. Example: a change in tax law could force rework, impacting the schedule by X and cost by Y. A risk management process must be undertaken, managing and mitigating risks and communicating them routinely and effectively to stakeholders |
| Assumption | Something set as true to enable progress, typically during planning and estimation. Example: assuming access to 10 skilled specialists for the entire project duration — that assumption enables the plan. If it turns out false the project is negatively impacted, so all assumptions must be monitored and managed so minimal impact occurs |
| Issue | Anything arising that must be dealt with to keep the project running smoothly. Issues differ from risks in that they exist as a problem today, unlike risks which might turn into issues in the future. Example: a key project resource has called in ill and is unlikely to attend for the rest of the week. Issues are managed through the issue management process |
| Dependency | Exists when an output from one piece of work is needed as mandatory input for another. Example: in a building project the architectural diagrams must be complete before the foundations can be laid. Managing inter-dependencies is critical regardless of project size |
Conway's Law
The organisation's communication structure must be reflected in the solution architecture design, and an optimised architecture might have an impact on the business by showing how work can be done more efficiently, or even just by exposing a gap. Therefore, if we understand the organisation's communication structure it helps us design the modules and components and assign the right responsibilities to them.
Beyond formal, well-defined communication channels there are informal ones — a daily coffee chat. Identifying both is crucial to understanding the real need of the solution.
Note also that multiple solutions may be identified, not just one — and the solution is not necessarily limited by the boundaries of the customer organisation, and can cover or support multiple capabilities at the same time.
As a solution architect, put more focus on stakeholders, business processes and all the relevant requirements. Identifying the right stakeholders and maintaining a good relationship with them is crucial. Understanding the solution-related business processes helps identify more stakeholders and clarifies what the solution must support. Requirements define everything, including the constraints that impact the solution.
Analysis techniques (BABOK)
| Technique | Use |
|---|---|
| Balanced Scorecard | Manage performance in any business model, organisational structure or process; a strategic planning and management tool measuring performance beyond traditional financial measures, across four dimensions: Learning and Growth, Business Process, Customer, Financial |
| Benchmarking & Market Analysis | Improve operations, increase customer satisfaction and value. Benchmark studies compare organisational practices against best-in-class practices, found in competitors, government or industry associations. The objective is to evaluate performance and ensure the enterprise operates efficiently |
| Business Capability Analysis | A framework for scoping and planning by generating shared understanding of outcomes, identifying alignment with strategy, and providing a scope and prioritisation filter |
| Business Cases | Justify a course of action based on benefits realised by the proposed solution compared to cost, effort and other considerations to acquire and live with it |
| Business Model Canvas | Describes how an enterprise creates, delivers and captures value for and from its customers |
| Business Rules Analysis | Identify, express, validate, refine and organise the rules that shape day-to-day business behaviour and guide operational decision making |
| Collaborative Games | Encourage participants in an elicitation activity to collaborate in building joint understanding of a problem or solution |
| Concept Modelling | Organise the business vocabulary needed to communicate domain knowledge consistently and thoroughly |
| Data Dictionary | Standardise the definition of a data element and enable common interpretation |
| Data Flow Diagrams | Show where data comes from, which activities process it, and whether output is stored or used by another activity or external entity |
| Data Mining | Improve decision making by finding useful patterns and insights from data |
| Decision Analysis | Formally assess a problem and possible decisions to determine the value of alternate outcomes under uncertainty |
| Document Analysis | Elicit information, including contextual understanding and requirements, by examining available materials describing the business environment or existing organisational assets |
| Estimation | Forecast cost and effort — top-down, bottom-up, parametric, rough order of magnitude, rolling wave, Delphi, PERT |
| Financial Analysis | Understand the financial aspects of an investment, solution or solution approach |
| Functional Decomposition | Manage complexity and reduce uncertainty by breaking processes, systems, functional areas or deliverables into simpler constituent parts, each analysable independently |
| Interface Analysis | Identify where, what, why, when, how and for whom information is exchanged between solution components or across solution boundaries |
| Interviews | A systematic approach to eliciting information by asking relevant questions and documenting responses |
| Item Tracking | Capture and assign responsibility for issues and stakeholder concerns that impact the solution |
| Lessons Learned | Compile and document successes, improvement opportunities, failures and recommendations for improving future projects or phases |
| Metrics and KPIs | Measure the performance of solutions, components and other matters of interest to stakeholders |
| Mind Mapping | Articulate and capture thoughts, ideas and information |
| Organisational Modelling | Describe the roles, responsibilities and reporting structures within an organisation and align them with its goals |
| Prioritisation | A framework to facilitate stakeholder decisions and understand the relative importance of information |
| Process Analysis | Assess a process for efficiency and effectiveness, and its ability to identify opportunities for change |
Benefits Dependency Network (BDN). Useful because it keeps focus on benefits realisation during programme execution, and allows variations of the project or programme to be assessed for their impact on benefits realisation. A well-constructed BDN tells the story of the project visually: in one diagram it shows why the programme is needed, what objectives it aims to achieve, how the organisation needs to change, and what projects must be undertaken. It can be read left-to-right or right-to-left, helps identify critical paths, can serve as the basis for the programme plan, and enables discussion of the relative contributions of the different projects — which in turn enables the right resource-allocation decisions.
Business processes are a huge topic not covered directly by this training, but there are indirect references — value streams, capability mapping — which are a great baseline for further discussion.
Exercises — Module 2
- Review the provided scenario
- Identify and document business drivers, goals and objectives
- Identify and document stakeholders (Name, Role, Group, Concerns, Views)
- Prioritise the stakeholders and create a power/interest matrix
- Identify the stakeholders' responsibilities, create a RACI
- Do functional decomposition: identify and document the main system capabilities — do not create a detailed WBS, that is out of scope of this homework
Module 3 — Quality Attributes and ASRs
Vocabulary
- Quality attribute — a measurable or testable property of a system used to indicate how well the system satisfies the needs of its stakeholders.
- Non-functional requirement (NFR) — defines the criteria used to evaluate the whole system rather than a specific behaviour; also called quality attributes and described in detail in architectural specifications.
- ASR (Architecturally Significant Requirement) — includes the most important requirements for architecture, whether functional or non-functional. An ASR directly impacts architecture design, whereas an NFR may or may not. That is why an ASR has more relevance than an NFR when referring to architecture requirements.
Only a subset of functional requirements, QA requirements and constraints are architecturally significant — the three sets intersect. In practice QA requirements and constraints are almost always ASRs; functional requirements more rarely. A typical functional ASR concerns integration: "integrate with a very old version of SAP."
"Significant" is ultimately measured by high cost of change — monetary or not (time, resources, reputation, opportunity cost). What counts as high is invariably project-specific: a $10,000 cost can be high for a small-budget project and low for a large one. Some cost measures can be entirely qualitative yet still identifiable in their ability to distinguish ASRs.
A trade-off point is one at which no solution satisfies all involved requirements equally well, so the architect must select a design option that compromises some requirements to meet others.
The ASR characterisation framework
From Characterizing Architecturally Significant Requirements (Chen, Ali Babar, Nuseibeh — IEEE Software, March/April 2013). An empirical grounded-theory study of 90 practitioners across four countries (58% US, 28% India, 13% Netherlands, 1% UK), who had collectively worked for 500+ distinct organisations, with more than 1,448 years of accumulated software development experience and 761 years in software architecture. 52% were architects, 20% executives, 14% managers, 8% consultants, 6% developers. Only concepts mentioned by at least two participants made the final findings.
The motivation matters: if ASRs are wrong, incomplete, inaccurate or lack detail, then an architecture based on them is also likely to contain errors. In practice stakeholders and requirements engineers frequently fail to express or effectively communicate ASRs to architects, preventing informed design decisions. This work sits within the twin peaks model, where problem and solution development interplay iteratively.
The framework has four sets of characteristics.
1. Definition
ASRs are those requirements that have a measurable impact on a software system's architecture. This delimits the portion of requirements that affects architecture in measurably identifiable ways. Empirically the distinction is real — participants did not perceive "temperature should be displayed in Celsius not Fahrenheit on this webpage" as architecturally significant, but did usually perceive "the system should provide five nines (99.999%) availability" as such.
"Significant" is measured by high cost of change — monetary or not. What counts as high is invariably project-specific.
2. Descriptions — how ASRs behave in the wild
| Description | What it means in practice |
|---|---|
| Hard to define and articulate | "Users usually find it difficult to articulate [ASRs], as many of them are about abstract and general concepts." And ASRs are expected to be ready early in the process, which adds to the difficulty |
| Tend to be described vaguely | Architects report receiving ASRs too vague to make informed decisions. Vague ASRs lead to bad decisions because architects make wrong assumptions about the missing details. The worked example: users requested the ability to receive notification about cash flows. Architects assumed email would be acceptable. During detailed design users explained they wanted real-time notification, the ability to subscribe to different account topics, and a UI showing all of this — which required publish-subscribe, a different architecture style entirely |
| Tend to be neglected initially | "Typically [ASRs] are overlooked in the early phase of a project" — from lack of initial awareness of their significant effects. "Users do not typically have a good understanding of [ASRs]; people who conduct requirement analysis often do not document them properly. … Users will not ask for them unless you are dealing with a highly tech-savvy group." Happens more with less-experienced teams. Many times requirements aren't recognised as architecturally significant until they've incurred a high cost — and at that stage rectifying mistakes can be costly |
| Tend to be hidden within other requirements | Following the way people spontaneously express requirements, ASRs usually aren't emphasised; they're embedded in other requirements' descriptions. Short phrases like "highly available system of 99.999 percent uptime" or "fault tolerant" are often mentioned only briefly while describing something else — but these phrases can significantly affect architecture. When architects receive ASRs hidden this way, they usually aren't sufficiently elaborated and lack the key details needed |
| Subjective | ASRs tend to be requested based on opinion rather than fact-based objective decisions. "[ASRs requested by customers] usually contain subjectivity — for example, 'The system should be available for 24/7' — whether it [needs to] be or not." Small differences in ASRs can lead to big differences in resulting architectures |
| Variable | ASRs change over time, usually unavoidably, owing to business and technology change. "Technology … is now changing so quickly that companies are viewing products as having a very limited (and short) lifetime before needing to be redesigned." ASRs also vary over space — consider similar systems engineered as a software product line |
| Situational | "A requirement is architecturally significant in one case, while being 'just a requirement' in the other case." Situational with respect to an existing architecture, a project's context or scope. A requirement might be significant where a "bad" architecture is in place but not where the architecture is "good". "A simple requirement in a smaller project might not be architecturally significant. Take the same requirement and enhance scope, add multiple interactions — then it could become significant" |
The consequence the authors draw: a definitive judgement usually can only be made when the requirement really incurs a high cost, or when the architect requires it to make architectural decisions. During requirements gathering we can only say certain requirements are likely to be architecturally significant. "Finding a definitive list of ASRs is not feasible. ASRs need to be dealt with individually."
3. Indicators — pragmatic hints without full cost estimation
Although cost of change is the measure of significance, getting an accurate cost is challenging, and cost estimation usually happens after requirements are gathered. Indicators give pragmatic hints instead.
| Indicator | Why it signals significance |
|---|---|
| Wide impact | When a requirement has wide impact — in terms of components, other requirements, code modules, stakeholders — it's usually architecturally significant. "[An ASR] has widespread impact across multiple components of the system"; "The more broadly a requirement and its resolution can be applied, the more significant it is" |
| Targeting trade-offs | A trade-off point is one where no solution satisfies all involved requirements equally well, so the architect must compromise some to meet others. Such requirements directly affect the outcome of architecture decisions. "The trade-offs are the weak points — the raw nerves — of the architecture. If a new requirement happens to (unintentionally) target these trade-offs … then the probability of it becoming architecturally significant is higher." When a requirement targets a trade-off point, the details, accuracy and precision of its description become critical |
| Strictness (constraining, limiting, non-negotiable) | Requirements satisfiable by multiple design options — or negotiable into such a form — allow flexibility in design. A strict requirement determines architectural decisions because it can't be satisfied by alternatives. "Our significant requirements were those that would be the limiting, or defining, characteristics of the product" |
| Assumption breaking | When designing, the architect makes fundamental assumptions, explicitly or implicitly — for example that turning down the server at midnight for maintenance is acceptable. Later this might no longer hold, and the requirement that breaks the assumption forces a different design |
| Difficult to achieve | Judging whether a requirement is difficult to achieve requires substantial knowledge of the solution space — which requirements engineers usually aren't expected to have. This limitation is precisely why the fourth set exists |
4. Heuristics — categories familiar to requirements engineers
Because indicators like difficult to achieve demand solution-space knowledge that requirements engineers typically lack, the framework offers heuristics: familiar categories where ASRs concentrate.
| Heuristic category | Look here |
|---|---|
| Quality attributes | The largest source. The paper's own list: Configurability, Flexibility, Interoperability, Performance, Recoverability, Scalability, Stability, Security, Portability, Reusability, Testability, Auditability, Sustainability, Supportability, Usability |
| Core features | The central functionality of the system |
| Constraints | Requirements that remove design freedom |
| Application environment | The context the system must operate within |
A closely related SEI source worth reading alongside it: Clements and Bass, Relating Business Goals to Architecturally Significant Requirements for Software Systems, CMU/SEI-2010-TN-018 — the origin of the eleven business-goal categories documented later in this module.
Quality attribute master list
| Operational | Developmental |
|---|---|
| Availability | Modifiability |
| Interoperability | Variability |
| Reliability | Supportability |
| Usability | Testability |
| Performance | Maintainability |
| Deployability | Portability |
| Scalability | Localizability |
| Monitorability | Development distributability |
| Mobility | Buildability |
| Compatibility | |
| Security | |
| Safety |
Definitions worth memorising:
| Attribute | Definition |
|---|---|
| Performance | The response of the system to performing certain actions for a certain period of time |
| Interoperability | An attribute of the system or part of it responsible for its operation and the transmission and exchange of data with other external systems |
| Usability | One of the most important attributes, because unlike other attributes users see directly how well it is worked out |
| Reliability | The ability to continue to operate under predefined conditions |
| Availability | Part of reliability; the ratio of available system time to total working time |
| Security | The ability to reduce the likelihood of malicious or accidental actions, and the possibility of theft or loss of information |
| Maintainability | The ability of the system to support changes |
| Modifiability | Determines how many common changes must be made to the system to make changes to each individual item |
| Testability | How well the system allows tests to be performed according to predefined criteria |
| Scalability | The ability to handle load increases without decreasing performance, or the possibility to rapidly increase the load |
| Reusability | The chance of using a component or system in other components/systems with small or no change |
| Supportability | The ability of the system to provide useful information for identifying and solving problems |
The term "non-functional requirements" is hard to trace, and it is probably not necessary to hunt for the first source. Many fundamental sources mention quality attributes as producing great influence on architecture. RUP was one of the first Agile/iterative methodologies widely adopted in enterprise software development. There is a controversial opinion expressed throughout the SEI series that only non-functional requirements define architecture. Even within SEI books there are opposing opinions on the value and meaning of "functional" and "non-functional" — Bass cautions against careless use of "functional", Clements against "non-functional".
Different sources categorise differently: Microsoft's guidance and the ISO/IEC 25010 standard produce categories, while the SEI approach does not group them. ISO/IEC 25010 gives the most verbose structure.
Do not rely too much on standard lists of quality attributes with the purpose of producing proper architecture. Those lists are a good starting point for having proper conversations with the client, and serve the purpose of not overlooking some important aspect of system design. Under certain conditions you can come up with a non-standard quality attribute that best describes some aspect of your requirements — something like Understandability may describe the steepness of the learning curve associated with a system's design. The SEI book even has a chapter with a methodology for such situations.
Quality attributes do not exist in a silo — they are connected and influence each other, and there are relations between quality attributes, functional requirements and constraints. Security may conflict with Usability; Performance may affect Maintainability. But there are also cases where achieving one makes another easier — Conceptual Integrity may help achieve better Maintainability. Consider these relations when designing, usually by accepting trade-offs.
The six-part general scenario
The SEI template that makes any quality attribute requirement testable:
Rendering diagram…
| Part | Meaning |
|---|---|
| Source of stimulus | Some entity — a human, a computer system, or any other actuator — that generated the stimulus |
| Stimulus | A condition that needs to be considered when it arrives at the system |
| Environment | The stimulus occurs within certain conditions. The system may be in an overload condition, or running, or some other condition may be true |
| Artifact | Some artifact is stimulated. This may be the whole system or some pieces of it |
| Response | The activity undertaken after the arrival of the stimulus |
| Response measure | When the response occurs it should be measurable in some fashion, so the requirement can be tested |
Example — modifiability: Source: developer. Stimulus: wishes to change the UI. Environment: at design time. Artifact: code. Response: modification is made, no side effects. Response measure: in 3 hours.
QA requirements can be tracked as acceptance criteria. Options for elaborating them: user stories; in SAFe, NFRs modelled as backlog constraints; as quality requirements or system quality tests; as technical debt; split into the Definition of Done; acceptance criteria of a user story; constraints in a user story.
Per-attribute scenario tables
Availability — a measure of the impact of failures and faults. Mean time to failure, mean time to repair, downtime. The probability the system is operational when needed, excluding scheduled downtime:
$$\alpha = \frac{\text{MTTF}}{\text{MTTF} + \text{MTTR}}$$
| Part | Options |
|---|---|
| Source | Internal, external |
| Stimulus | Fault: omission, crash, timing, response |
| Artifact | Processors, channels, storage, processes |
| Environment | Normal, degraded |
| Response | Logging, notification, switching to backup, restart, shutdown |
| Measure | Availability, repair time, required uptime |
Concrete (a crossing gate controller): main processor fails to receive an acknowledgement from the gate processor. Source: external to system. Stimulus: timing. Artifact: communication channel. Environment: normal operation. Response: log failure and notify operator via alarm. Measure: no downtime.
Interoperability — the degree to which two or more systems can usefully exchange meaningful information in a particular context. Exchanging data is syntactic interoperability; interpreting exchanged data is semantic interoperability. Purposes: to provide a service, and to integrate existing systems into a system of systems (SoS). The service may need to be discovered at runtime or earlier.
| Part | Options |
|---|---|
| Source | A system |
| Stimulus | A request to exchange information among systems |
| Artifact | The systems that wish to interoperate |
| Environment | Systems wishing to interoperate are discovered at run time, or known prior to run time |
| Response | The request is appropriately rejected and appropriate entities (people or systems) notified; or appropriately accepted and information successfully exchanged and understood; or logged by one or more of the involved systems |
| Measure | Percentage of information exchanges correctly processed; percentage correctly rejected |
Concrete: our vehicle information system sends our current location to the traffic monitoring system, which combines it with other information, overlays it on a Google Map and broadcasts it. Source: vehicle information system. Stimulus: current location sent. Artifact: traffic monitoring system. Environment: systems known prior to runtime. Response: traffic monitor combines, overlays and broadcasts. Response measure: our information included correctly 99.9% of the time.
Performance — event arrival patterns are periodic (fixed frequency), stochastic (probability distribution) or sporadic (random). Event servicing concerns latency (time between arrival of the stimulus and the system's response), jitter (variation in latency), throughput (number of transactions per second), and events and data not processed.
| Part | Options |
|---|---|
| Source | External, internal |
| Stimulus | Event arrival pattern |
| Artifact | System services |
| Environment | Normal, overload |
| Response | Change operation mode? |
| Measure | Latency, deadline, throughput, jitter, miss rate, data loss |
Concrete: main processor commands the gate to lower when a train approaches. Source: external — arriving train. Stimulus: sporadic. Artifact: system. Environment: normal mode. Response: remain in normal mode. Measure: send signal to lower gate within 1 millisecond.
Security — six properties:
| Property | Meaning |
|---|---|
| Non-repudiation | Cannot deny the existence of an executed transaction |
| Confidentiality | Privacy — no unauthorized access. A hacker cannot access your income tax returns |
| Integrity | Information and services delivered as intended and expected. Your grade has not been changed since your instructor assigned it |
| Authentication | Parties are who they say they are |
| Availability | No denial of service — a DoS attack won't prevent you from ordering a book. A clear intersection between Security and Availability |
| Authorization | Grant users privileges to perform tasks |
| Part | Options |
|---|---|
| Source | User/system, known/unknown |
| Stimulus | Attack to display info, change info, access services and info, deny services |
| Artifact | Services, data |
| Environment | Online/offline, connected or disconnected |
| Response | Authentication, authorization, encryption, logging, demand monitoring |
| Measure | Time, probability of detection, recovery |
Concrete: hackers are prevented from disabling the system. Source: unauthorized user. Stimulus: tries to disable system. Artifact: system service. Environment: online. Response: blocks access. Measure: service is available within 1 minute.
Modifiability — three questions: What can change? When is it changed? Who changes it?
| Part | Options |
|---|---|
| Source | Developer, system administrator, user |
| Stimulus | Add/delete/modify function or quality |
| Artifact | UI, platform, environment, external system |
| Environment | Design, compile, build, run time |
| Response | Make change, test it, deploy it |
| Measure | Effort, time, cost, risk |
Concrete (a restaurant locator app): the user may change the behaviour of the system. Source: end user. Stimulus: wishes to change the locale of search. Artifact: list of available country locales. Environment: runtime. Response: the user finds an option to download a new locale database; the system downloads and installs it successfully. Measure: download and installation occur automatically.
Module interdependencies that drive modifiability: data types; interface signatures, semantics, control sequence; runtime location, existence, quality of service, resource utilization.
Testability — the ease with which software can be made to demonstrate faults through testing. Assuming the software has one fault, the probability of fault discovery on the next test execution. You need to control components' internal state and inputs, and observe components' output to detect failures. Testing activities can consume up to 40% of a project.
| Part | Options |
|---|---|
| Source | Developer, tester, user |
| Stimulus | Project milestone completed |
| Artifact | Design, code component, system |
| Environment | Design, development, compile, deployment, or run time |
| Response | Can be controlled to perform the desired test and results observed |
| Measure | Coverage; probability of finding additional faults given a fault; time to test |
Concrete (a photo editor): new versions can be completely tested relatively quickly. Source: system tester. Stimulus: integration completed. Artifact: whole system. Environment: development time. Response: all functionality can be controlled and observed. Measure: entire regression suite completed in under 24 hours.
Testability tactics split into control and observe system state — specialized interfaces, record/playback, localize state storage, abstract data sources, sandbox, executable assertions — and limit complexity — limit structural complexity, limit non-determinism.
Usability — ease of learning system features (learnability), ease of remembering (memorability), using a system efficiently, minimizing the impact of errors (understandability), and increasing confidence and satisfaction.
| Part | Options |
|---|---|
| Source | End user |
| Stimulus | Wish to learn/use/minimize errors/adapt/feel comfortable |
| Artifact | System |
| Environment | Configuration or runtime |
| Response | Provide ability or anticipate (support good UI design principles) |
| Measure | Task time, number of errors, user satisfaction, efficiency, time to learn |
Concrete (restaurant locator): the user may undo actions easily. Source: end user. Stimulus: minimize impact of errors. Artifact: system. Environment: runtime. Response: wishes to undo a filter. Measure: previous state restored within one second.
Usability tactics split into support user initiative — cancel, undo, pause/resume, aggregate — and support system initiative — maintain task model, maintain user model, maintain system model. Both aim at the user being given appropriate feedback and assistance.
Other architecturally significant usability scenarios worth recognising, each with real architectural implications: aggregating data; cancelling commands; using applications concurrently; maintaining device independence; recovering from failure; reusing information; supporting international use; navigating within a single view; working at the user's pace; predicting task duration; comprehensive search support.
Design decisions and tactics
A system design is a collection of design decisions. Some respond to quality attributes, some to achieving functionality. A tactic is a design decision to achieve a quality attribute response, and tactics are a building block of architecture patterns — a more primitive, granular, proven design technique that sits between stimulus and response, controlling the response.
Tactics are atoms, patterns are molecules. The focus of a tactic is on a single quality attribute response; within a tactic there is no consideration of trade-offs. Trade-offs must be explicitly considered and controlled by the designer. In this respect tactics differ from architectural patterns, where trade-offs are built into the pattern. From a practical standpoint SEI tactics give only a very high-level overview of possible approaches — like quality attribute checklists, they help start a proper conversation with clients and help avoid overlooking something.
Seven categories of design decision:
- Allocation of responsibilities — system functions to modules
- Coordination model — module interaction
- Data model — operations, properties, organization
- Resource management — use of shared resources
- Architecture element mapping — logical to physical entities: threads, processes, processors
- Binding time decisions — variation of the lifecycle point of module "connection"
- Technology choices
Design checklists give design considerations for each QA, organised by design decision category. For allocation of system responsibilities under performance: which responsibilities will involve heavy loading or time-critical response? What are the processing requirements, and will there be bottlenecks? How will threads of control be handled across process and processor boundaries? What are the responsibilities for managing shared resources?
The utility tree
Captures all QA requirements (ASRs) in one place. "Utility" expresses the overall "goodness" of the system.
Rendering diagram…
Construction rules:
- The most important QA goals are the high-level nodes — typically performance, modifiability, security and availability
- Scenarios are the leaves
- Output: a characterization and prioritization of specific quality attribute requirements
- Two ratings per scenario: High/Medium/Low importance for the success of the system, and High/Medium/Low difficulty to achieve (the architect's assessment)
Key: H = high (must-have), M = medium (important), L = low (nice-to-have).
The canonical SEI example (the Nightingale system):
| Quality Attribute | Attribute Refinement | ASR | Priority |
|---|---|---|---|
| Performance | Transaction response time | A user updates a patient's account in response to a change-of-address notification while the system is under peak load, and the transaction completes in less than 0.75 second | (H, M) |
| Performance | Transaction response time | The same, while the system is under double the peak load, and the transaction completes in less than 4 seconds | (L, M) |
| Performance | Throughput | At peak load, the system is able to complete 150 normalized transactions per second | (M, M) |
| Usability | Proficiency training | A new hire with two or more years' experience in the business becomes proficient in the core functions in less than 1 week | (M, L) |
| Usability | Proficiency training | A user in a particular context asks for help, and the system provides help for that context within 3 seconds | (H, M) |
| Usability | Normal operations | A hospital payment officer initiates a payment plan for a patient while interacting with that patient, and completes the process without the system introducing delays | (M, M) |
| Configurability | User-defined changes | A hospital increases the fee for a particular service. The configuration team makes the change in 1 working day; no source code needs to change | (H, L) |
| Maintainability | Routine changes | A maintainer encounters search- and response-time deficiencies, fixes the bug, and distributes the fix with no more than 3 person-days of effort | (H, M) |
| Maintainability | Routine changes | A reporting requirement requires a change to the report-generating metadata. The change is made in 4 person-hours of effort | (M, L) |
| Maintainability | Upgrades to commercial components | The database vendor releases a new version that must be adopted | — |
Sometimes a simple table rather than a tree is better for a utility tree — it is more readable and maintainable. A tree is good during whiteboarding. Feel free to use either.
Careful with attribution: a DDoS attack is not an ASR — preventing a DDoS attack is. Availability, Performance and Usability are all affected by a DDoS attack, but prevention belongs under Security.
Quality Attribute Workshops
| Variant | Notes |
|---|---|
| QAW (SEI) | Usually hard to organise because it requires the presence of all key stakeholders at the same time, actively involved. As requirements complexity or system size increases, it makes sense to conduct the full QAW |
| Abbreviated workshop | Easier to organise because it needs less time and fewer people. Several documented variants exist, and most consultancies keep their own. Suits a moderate system with a reasonably clear domain |
| Architect-led elicitation | The lightest form: the architect drafts the scenarios and validates them individually with stakeholders. Depends heavily on the architect's experience, and suits small-scale, simple requirements — not a complex or unfamiliar business domain |
The eight QAW steps:
- QAW overview and introductions — obtain the list of attendees, take notes as appropriate
- Business/mission presentation — capture driving quality attributes, issues, notes
- Architectural plan presentation — capture driving quality attributes, issues, notes
- Identification of architectural drivers — share the information from steps 2 and 3, then after a few minutes ask for clarifications and corrections to the list of architectural drivers. That list helps facilitators ensure coverage during scenario brainstorming
- Scenario brainstorming — elicit raw scenarios from the stakeholder community in round-robin fashion, using a raw scenario table
- Scenario consolidation — merge similar and duplicate scenarios using stakeholders' input
- Scenario prioritization — each stakeholder gets votes equal to 30% of the total number of scenarios generated
- Scenario refinement — fully develop the scenario to include details such as how long, how much, how often, when, environment, who
The typical ASR process: Collect → Categorize → Review/Refine → Prioritize. For each "capture" step there can be one or more "refine" steps.
Deriving ASRs from business goals
Eleven categories of business goal. They are not completely orthogonal — some goals fit more than one category, and that is all right.
| Category | Content |
|---|---|
| Contributing to the growth and continuity of the organisation | If the system were not successful, the organisation would cease to exist |
| Meeting financial objectives | The system may be for sale, either standalone or by providing a service, in which case it generates revenue |
| Meeting personal objectives | From "I want to enhance my reputation by the success of this system" to "I want to learn new technologies" |
| Meeting responsibility to employees | For developers: ensuring certain types of employees have a role, or providing opportunities to learn new skills. For operators: safety, workload, or skill considerations |
| Meeting responsibility to society | Some organisations see themselves as being in business to serve society. Topics: resource usage, green computing, ethics, safety, open source issues, security, privacy |
| Meeting responsibility to the state | Regulatory conformance or supporting government initiatives |
| Meeting responsibility to shareholders | Liability protection and certain types of regulatory conformance such as Sarbanes-Oxley |
| Managing market position | Increase or hold market share, various types of intellectual property protection, time to market |
| Improving business processes | Improved processes may enable new markets, new products, or better customer support |
| Managing the quality and reputation of products | Branding, recalls, types of potential users, quality of existing products, testing support and strategies |
| Managing change in environmental factors | Encourages stakeholders to consider what might change in the business goals for a system |
Non-architectural solutions are legitimate outcomes: "to optimize the budget, decrease the salary of the employees"; "to allow a user-friendly way to edit rich text, buy a licence for Microsoft Word."
This really describes the essence of the difference between a software architect and a solution architect. A solution architect addresses business goals, which likely — but not necessarily — includes building software elements.
Maintainability / Modifiability in depth
Maintainability is one of the key quality attributes present in almost any categorisation from any source. SEI gives a slightly different name to the attribute with the same meaning — Modifiability. ISO/IEC 25010 differentiates Maintainability and Modifiability but essentially the meaning is the same: the ease of applying a change to a product or system.
In practice we frequently deal not with building solutions from the ground up but with adding features to existing solutions, re-platforming, updating technology stacks and similar. Code is read far more frequently than it is written.
It is usually said that only one requirement is always stable — the inevitability of change.
Changes arise constantly: requirements change frequently even before the system reaches its intended users, and as the system is used the need for additional features arises and bugs are revealed. Most of the cost of a typical software system occurs after it has been initially released.
Three important ramifications of the SEI cost-of-modifiability formula:
- The cost of making a system more modifiable may vary substantially — from development cost where a developer applies changes through code, to visual configuration where end-users apply changes and see results immediately (CMS systems)
- The cost of making a system adaptable to changes should imply the potential costs of applying those changes
- As systems evolve, other configuration mechanisms get added — the later you add those mechanisms, the higher the cost
Binding is the concept SEI uses heavily to elaborate on architecture flexibility. Binding time decisions heavily influence maintainability: the more choices to bind a value to a specific parameter exist, the more flexible the system. The value can be anything depending on scale — from reading a single value from configuration, to replacing a component during runtime via DI or service location. Late binding is usually considered more flexible than early binding, but that comes at the cost of implementing specific infrastructure for late binding.
Tools do not usually provide much help in increasing architecture maintainability. Static code analyzers such as NDepend help get an initial feeling for a system's complexity, but when it comes to real re-factoring or re-architecting such tools rarely provide thorough guidance. What does help: unified coding standards verified by linters; conducting architecture and code reviews; keeping an up-to-date backlog of technical, design and architecture debt.
Do not underestimate the value of conformity of architecture and code — practice tells that the maintainability of a solution where the same approaches are used everywhere is dramatically higher.
Note cohesion and coupling — very ubiquitous principles applicable at almost all levels.
Performance in depth
Performance is the quality attribute articulated explicitly in almost all requirements documents. If it is not articulated, the rule of thumb is to ask about it. If it is considered that there are no specific performance requirements, there still are some — always double-check with the client what their performance expectations are, because sometimes you will be surprised. The best method to check whether performance complies with expectations and the SLA is performance testing.
Key characteristics: bandwidth, latency, response time, throughput — usually articulated in the measure part of a scenario. Less common: the jitter of the response (allowable variation in latency), and the number of events not processed because the system was too busy to respond.
SEI gives two general tactic groups to achieve performance requirements: control resource demand and manage resources. The most ubiquitous tactics: Prioritize Events, Reduce Overhead, Increase Resource Efficiency, Increase Resources, Introduce Concurrency, Maintain Multiple Copies of Computations, Maintain Multiple Copies of Data, Schedule Resources. Some are highly specific — Manage Sampling Rate applies only to streaming data processing — while others such as Increase Resource Efficiency are generic.
Types of performance testing
| Type | Purpose |
|---|---|
| Load testing | Understand the behaviour of the system under a specific expected load — the expected concurrent number of users performing a specific number of transactions within a set duration |
| Stress testing | Understand the upper limits of capacity within the system |
| Soak testing (endurance) | Determine whether the system can sustain the continuous expected load |
| Spike testing | Suddenly increase or decrease the load generated by a very large number of users and observe behaviour. Determine whether performance will suffer, the system will fail, or it will handle dramatic changes |
Others exist — configuration testing, isolation testing. It is not required to remember every type, but it is important to understand the approaches and tools that measure performance in different circumstances.
A very good piece of advice: analyse performance on production data and in production environments. A very common mistake is evaluating system performance against data that is not similar to production data. Keep the performance testing environment very close to production, otherwise you run a high risk that results will not reflect the real state of things.
Analyse the error log and any other tracing captured during a test. When there is an error, take a memory dump and analyse it. Performance optimization is hard — always measure and use profilers such as Dynatrace or dotTrace.
Fowler's story (from the first edition of Refactoring): he and a colleague were invited to analyse performance problems in an enterprise-grade application. While they travelled, the development team held several brainstorming meetings on which aspects they might improve, and came up with a list of good ideas. When Fowler arrived he did not want to look at the list — the developers were offended — and instead ran a profiler against the code. The results showed the major bottleneck was the method for working with string objects. Once resolved, they achieved such a significant boost that no other improvements were necessary. Working with string objects had not been identified as a problem in the developers' original list. Lesson: when it comes to performance, always measure, don't guess.
Be careful analysing stakeholders' requirements: performance is usually a requirement even when not mentioned explicitly — however, high performance is usually very expensive to achieve.
Scalability
There are many definitions, and they all revolve around the system's ability to handle increased load while maintaining the expected SLA. Scalability might be considered a kind of Modifiability/Maintainability, but it became so popular with the advent of cloud computing and microservices that it is usually treated as a standalone quality attribute.
Two basic kinds: vertical (scaling up) and horizontal (scaling out). Horizontal scalability always implies the system is distributed; vertical scalability applies to both standalone monolithic and distributed architectures.
The scale cube
| Axis | Meaning | Applicability |
|---|---|---|
| Y axis | Functional decomposition | Can be applied to any system — monolith or distributed |
| X axis | Cloning | Applied to distributed systems; beneficial when some elements can be cloned — stateless design, load balancing |
| Z axis | Data sharding / partitioning | Applied to data infrastructure. Not every system can benefit — sharding/partitioning is a challenging concept for many databases |
Selected scalability rules (Abbott, Scalability Rules)
Mostly applicable to web information systems.
| Rule | Content |
|---|---|
| 19 | BASE — an acronym for architectures that solve CAP: "basically available, soft state, and eventually consistent." By relaxing the ACID property of consistency we gain greater flexibility in how we scale; a BASE architecture allows databases to become consistent eventually. Frequently used in NoSQL databases |
| 25 | Use cache to help scale the persistence layer |
| 29 | Always have the ability to roll back code. Ensure that all releases can roll back, practise it in a staging or QA environment, and use it in production when necessary to resolve customer incidents. If you haven't experienced the pain of not being able to roll back, you likely will at some point if you keep playing with the "fix-forward" fire |
| 35 | Don't use SELECT * in queries. Two primary problems: the probability of data-mapping problems, and the transfer of unnecessary data |
| 46 | Do not rely on vendor products, services or features to scale your system. Keep your architecture simple, your destiny in your own hands, and your costs in control. All three can be violated by relying on a vendor's proprietary scaling solution |
| 50 | Be competent, or buy competency in, for each component of your architecture. To a customer, every problem is your problem — you can't blame suppliers or providers. You provide a service, not software. Don't confuse competence with build-versus-buy or core-versus-context decisions: you can buy solutions and still be competent in their deployment and maintenance. In fact your customers demand that you do |
Other high-level influences on scalability: whether the system leverages on-premise or cloud infrastructure (hybrid approaches and private clouds exist, and hybrid is becoming more common for medium and large systems); stateful or stateless design, where stateless components generally scale better but at the cost of storing state externally and making extra calls to get and save state data. Scalability testing is challenging and tightly related to performance testing.
Listen to your clients but always try to differentiate the real needs of the business from the wishes of very specific stakeholders. Ultimate scalability is very expensive to achieve — be mindful whether it is what is really needed.
Reliability, faults, errors, failures
Reliability is tightly coupled with fault tolerance, and under some conditions can be treated as a synonym — though not in all cases. Some sources don't define reliability as standalone and unite it with availability: "in fact, availability builds upon the concept of reliability by adding the notion of recovery — that is, when a system breaks, it repairs itself."
The precise chain (Hanmer, Patterns for Fault Tolerant Software):
| Term | Definition |
|---|---|
| Failure | Occurs when the delivered service no longer complies with the specification — the agreed description of the system's expected function or service. Examples: the system crashes to a stop when it shouldn't; it computes an incorrect result; it is not available for service; it is unable to respond to user interaction. Whenever the system does the wrong thing it has failed. Failures are detected by the observer and users of the system |
| Error | That part of the system state liable to lead to subsequent failure; an error affecting the service is an indication that a failure occurs or has occurred. It is incorrect system behaviour from which a failure may occur. Two types: timing or value. Value errors might be incorrect discrete values or incorrect system state; timing errors can include total non-performance (the time was infinite) |
| Fault | The adjudged or hypothesized cause of an error — the defect present in the system that can cause an error, the actual deviation from correctness. In a program it is the misplaced comma or period, or the missing break in a C++ switch. Colloquially called a "bug". It might be a latent software defect, or a garbled message received on a communications channel. In general, neither the software nor the observers are aware of the presence of a fault until an error occurs |
Common errors:
- Timing or race conditions — communicating processes get out of synchronization and a race for resources occurs
- Infinite loops — continuous execution of a tight loop without pausing and without acknowledging others' requests for shared resources
- Protocol errors — errors in the messaging stream from non-conformance with the protocol: unexpected messages, messages sent at inappropriate times, or out of sequence
- Data inconsistency — data differs between two locations, e.g. memory and disk, or between different network elements
- Failure to handle overload conditions — the system is unable to handle the workload
- Wild transfer or wild write — data written to an incorrect memory location, or a transfer to an incorrect location, if there is a fault
There is a special mindset for developing fault-tolerant systems, and key principles — some applicable to all systems, others only under certain conditions. Running experiments directly in production implies substantial maturity in monitoring, recovery and resiliency; it is not recommended unless you satisfy all the prerequisites and understand the potential impact of the worst case.
Netflix is the industry's good example of a highly reliable fault-tolerant system, running tests directly in production to evaluate and measure the impact of removing components or injecting errors into the execution flow. Some elements remove components running in production; others search for unused resources and non-compliance and apply fixes; yet others search for security vulnerabilities. These approaches proved efficient for achieving high reliability, but again are not recommended without mature operations and monitoring practices and a robust environment and architecture supporting resiliency and self-healing.
Availability mathematics
Almost any software SLA tries to provide availability claims. Scheduled downtimes may not be considered when calculating availability, because the system is deemed "not needed" then — but of course this depends on the specific requirements, often encoded in the SLA.
| Nines | Approximate downtime per year |
|---|---|
| 99% | ~3.65 days |
| 99.9% | ~8.76 hours |
| 99.99% | ~52.6 minutes |
| 99.999% | ~5.26 minutes |
The conclusion from real IT industry examples is that achieving more than 99% availability may be much more challenging than it seems at first glance. When someone requests more than three nines availability, be extra careful — if that is a real requirement, it will be very expensive to achieve.
Composition rules (the practical formulas from the Module 9 homework guide, which are the same maths you need here):
Series — components that are single points of failure — multiply:
$$A_{total} = A_1 \times A_2 \times A_3 \times \dots \times A_n$$
Redundancy of m identical copies of a component — one minus the probability that all copies are unavailable:
$$A_{component} = 1 - (1 - A_1)^m$$
A component's total fair availability includes both the infrastructure it runs on (hardware + OS + provided software) and the software itself, because each can fail:
$$A_{component} = A_i \times A_s$$
Both formulas assume the basic scenario: copies are fully identical with the same availability and work constantly (no partial operation or unequal availability), and one software component runs per one infrastructure component — virtualisation with VMs and containers makes the calculation more complex.
Cloud specifics. Often you use existing IaaS/PaaS/SaaS services, so you do not calculate availability from scratch but rely on the numbers published by the provider — use the service SLA to estimate total availability. What adds real complexity is that each cloud can use its own definitions (for example, what "unavailability" means) and can have many exclusions, so always read what is written at the end of the agreement.
The tricky example: Amazon's SLA for EC2 uses a region-based approach and provides a fixed 99.99% only if you run EC2 in 2 or more Availability Zones — and this number does not increase if you use 3 or more zones. As a result, 99.99% is the maximum for one region. If you want better, you need to plan across different regions.
The formulas apply to both software and hardware components. SEI availability tactics include the obvious and popular ones: Monitor, Heartbeat, Redundancy, Exception Handling, Retry.
Security in depth
Threat modelling is the technique and toolset that helps understand potential security challenges and concerns — for example investigating how secure a web service and its environment are. You usually need a security expert involved in security design and testing if there are very specific and detailed security requirements; a security competence centre can perform threat modelling and other consulting as a service.
STRIDE is a threat classification model developed by Microsoft for reasoning about security threats. It was initially created as part of the threat modelling process and is used in conjunction with a model of the target system constructed in parallel, including a full breakdown of processes, data stores, data flows and trust boundaries.
| Letter | Threat |
|---|---|
| S | Spoofing |
| T | Tampering |
| R | Repudiation |
| I | Information disclosure |
| D | Denial of service |
| E | Elevation of privilege |
OWASP — an industry initiative gathering knowledge about the most common security threats and methods for preventing them. The OWASP Top Ten is a powerful awareness document representing a broad consensus about the most critical web application security flaws, produced by security experts worldwide and published annually. OWASP also provides a free tool for web application security testing that can be injected into a CI/CD pipeline to enable continuous security verification (DevSecOps).
Always understand your security testing methodology and strategy — other types such as penetration testing can be leveraged. Everything is driven by the requirements and the type of solution you are building.
Other quality attributes
You will find information on many other quality attributes, and that should not be a surprise: there is no single one-size-fits-all list. Refer to ISO/IEC 25010 section 4.2 for a substantial list.
Remember: knowing quality attribute lists, tactics and patterns is a very good starting point for having proper conversations with clients. For creating good architectures you have to analyse the broader picture — other ASRs, business needs, industry reference architectures and similar.
Common pitfalls in ASR gathering
| Pitfall | Description |
|---|---|
| The "shopping cart" mentality | Stakeholders' false impression that specifying requirements is like filling up a shopping cart |
| The "this is too technical for me" attitude | Stakeholders treating ASR gathering as less important than, for example, use-case modelling |
| The "all requirements are equal" fallacy | Giving all requirements the same priority — mostly as high |
| The "requirements that can't be measured" syndrome | "The system must be always available and very performant" |
| The "not enough time" complaint | — |
| The "all stakeholders are alike" misconception | Address the right questions to the right people — always classify stakeholders as learned in Business Architecture |
Making quality attributes measurable
A quality attribute you cannot measure is not a requirement, it is a wish. The table below is a compiled metric vocabulary per attribute — it is what "define a set of measurable metrics" actually means. The guidance: select the 3–5 most important quality attributes, give the motivation for selecting each, list them for both baseline and target architecture, and note the component where each metric is measured.
| Quality attribute | Candidate measurable metrics |
|---|---|
| Conceptual Integrity | List of design patterns and styles to be used; afferent coupling (Ca); efferent coupling (Ce) |
| Maintainability | Cyclomatic complexity; type size; percentage of comments; efferent coupling at type level (Ce) |
| Re-usability | List of exact components/libraries that must be re-usable; re-usable code base percentage |
| Availability | Availability excluding planned downtime (%); planned downtime (minutes per day/week/month); time required to update software/hardware on the running system (minutes) |
| Interoperability | List of exact supported integration protocols/standards; backward compatibility for integration API (%); integration API breaking changes (%) |
| Manageability | System logs collected (yes/no); logging level changeable at runtime (yes/no); troubleshooting tools exist, actual, documented and known to administrators (yes/no); monitored by third-party tools (yes/no); exact list of information collected/traced/monitored for diagnostics and troubleshooting |
| Performance | Estimated end-users by location (total); concurrent users per location (average/peak); data storage size and estimated growth per year; number of records/documents in storage; mean page load time (ms); mean function call time (ms) |
| Reliability | Failure rate (failures per unit time); MTTF; MTTR; MTBF; time to switch to disaster recovery environment (seconds); number of Critical and High severity customer-reported bugs |
| Scalability | Architecture allows horizontal scaling (yes/no); time to scale up/down (seconds/minutes); scaling limits sufficient for the domain (servers, network bandwidth, disk); exact components that must scale out; exact scale-out conditions |
| Security | PII security scenarios; ability to detect DDoS (yes/no); ability to react to DDoS (yes/no); access restricted by authentication/authorization (yes/no); prevents SQL injection (yes/no); prevents XSRF/CSRF (yes/no); secured connection (yes/no); password encryption (yes/no); audits and logs all user interaction for critical operations (yes/no); sensitive data protected — encrypted, not logged, secure channels only |
| Testability | Unit test coverage (%); integration test coverage (%); exact list of required test environments (functional, performance, security); exact list of test approaches (manual/automated, unit, end-to-end, regression, integration) |
| Auditability | List of operations that must leave an audit trail in 100% of cases; exact parameters about users and their activities recorded for audit |
| Usability | Reference to the specific UI/UX guideline to follow; list of devices, resolutions, OS versions, browsers/versions, locales/cultures to support; Section 508 support for people with disabilities (yes/no); accelerators such as hotkeys and suggestion lists; number of clicks to reach particular functionality; mean time for an average user to get used to the system (minutes) |
Quality attributes under a service-oriented architecture
Quality Attributes and Service-Oriented Architectures (SEI, CMU/SEI-2005-TN-014) exists because software architecture is the bridge between mission/business goals and a software-intensive system, and quality attribute requirements drive architecture design — so it matters how a chosen style supports them.
The report's status column rates the maturity of SOA in each area: green = known solutions on relatively mature standards and technology; yellow = some solutions exist but need further research to prove usefulness; red = standards and technology immature, significant further effort required.
| Quality attribute | SOA's effect | Status |
|---|---|---|
| Interoperability | Underlying standards give good interoperability technology-wise, letting services built in different languages on different platforms interact. However semantic interoperability is not fully addressed — those standards are immature and still being developed | 🟢 Green |
| Extensibility | Extending an SOA by adding new services or incorporating additional capabilities into existing ones is well supported — but the interface/formal contract must be designed carefully so it can be extended without breaking consumers | 🟢 Green |
| Reliability | Problems can occur in many areas, but WS-Reliability and WS-ReliableMessaging should mean messages are transmitted reliably. Service reliability is still an issue | 🟡 Yellow |
| Availability | It is up to the service users to negotiate an SLA setting an agreed level of availability with penalties for noncompliance. Availability improves if a provider builds in contingencies such as exception handling that dynamically locates another source for the needed service | 🟡 Yellow |
| Usability | May decrease if the services support human interaction and there are performance problems with those services | 🟡 Yellow |
| Scalability | There are ways to handle more service users and more requests, but these solutions require detailed analysis by the providers to ensure other quality attributes aren't negatively impacted | 🟡 Yellow |
| Adaptability | SOA should have a positive impact, as long as the adaptations are anticipated. But it is left up to users and providers and no standards support it; must be managed in coordination with stability and performance | 🟡 Yellow |
| Operability and Deployability | Operating and deploying services and systems that use them requires deliberate support | 🟡 Yellow |
| Security | The need for encryption, authentication and trust requires detailed attention within the architecture. Many standards are being developed (SAML, XACML) but most are still immature | 🔴 Red |
| Performance | SOA can have a negative impact due to network delays, the overhead of looking up services in a directory, and XML parsing in web services. The architecture must be evaluated carefully and providers must design and evaluate their services carefully | 🔴 Red |
| Testability | Negatively impacted by the complexity of testing services distributed across a network. Those services might be provided by external organisations with no source code access, and if they implement runtime discovery it may be impossible to identify which services are used until the system executes | 🔴 Red |
| Auditability | Negatively impacted if end-to-end auditing capabilities aren't built in by the service users | 🔴 Red |
The report's own caveat, which is the real lesson: as with any architecture, trade-offs between quality attribute requirements must be made, and the resulting decisions may impact the organisation's ability to meet its business goals. In each system the quality attributes must be characterised specifically — using scenarios — and then weighed against this information.
Worked example — ASRs for Lumen Diagnostics
The Module 3 exercise done against the case study. The Priority column carries two values: business value and architectural impact, in that order.
Functional ASRs
Most functional requirements are not architecturally significant. These are, and note how many of them are about integration — that is the usual pattern.
| # | Functional ASR | Bus | Arch | Why it is architecturally significant |
|---|---|---|---|---|
| F01 | Intelligent search across partner availability and manually uploaded slots | M | H | Cannot be served from the transactional store at acceptable latency — implies a dedicated search component and an indexing path, which changes the data flow |
| F02 | Automated integration with one partner group's scheduling API | M | M | Introduces an outbound synchronous dependency on a third party, with its own failure and latency behaviour |
| F03 | Manual integration path for the remaining ~600 partners | M | H | Two very different ingress paths for the same domain concept. Points to one partner-availability API consumed by both the manual upload UI and the automated adapter, rather than two parallel implementations |
| F04 | The appointment workflow must be changeable and extensible after go-live | H | H | The stage list is stated as a requirement and as something that will change. Hard-coding the seven stages fails the second half — pushes toward an externalised workflow definition |
| F05 | Consolidate multiple studies for one patient into a single visit | M | M | Introduces a grouping aggregate above the appointment, affecting the domain model and the booking transaction boundary |
| F06 | Single sign-on across patient and administration portals | M | M | Determines the identity architecture and the trust boundary between patient-facing and staff-facing surfaces |
Quality attribute ASRs
| # | QA ASR | Bus | Arch | Note |
|---|---|---|---|---|
| QA01 | Patient and Administration portals available 99.9%; Partner portal 99% | M | H | Negotiate this. Availability is priced in redundancy — see the cost-of-outage arithmetic in Module 6 before agreeing a figure |
| QA02 | Routine screens respond within 2 s at the 95th percentile | H | H | The customer said "feel immediate". This makes it testable: a percentile, not an average |
| QA03 | Daily operational reports within 60 s; analytical reports within 10 minutes | M | M | Splits reporting by class, because one number for both is unachievable or wasteful |
| QA04 | Full functionality on phones and tablets | H | H | Forces the native-versus-responsive-web decision, which is architectural, not cosmetic |
| QA05 | Patient data held in the jurisdiction where it was collected | H | H | Given planned expansion outside the current jurisdiction, this constrains the deployment topology and the data model |
| QA06 | Support 4,200 concurrent users, absorbing 12% annual growth | H | H | Derived from 52,000 named users at ~8% concurrency, plus the stated growth assumption |
| QA07 | Serve new regions; outside the primary region p95 must not degrade by more than 50% | M | H | Turns "we will enter two more regions" into a measurable latency obligation |
| QA08 | Promotion of a release causes no more than 10 minutes of reduced service | M | M | Makes "robust promotion procedures" measurable, and effectively selects a deployment strategy |
| QA09 | All authenticated traffic over TLS 1.3 or better | M | M | Already specific in the source — carry it through unchanged |
| QA10 | A clinical-protocol or policy change is applied by the configuration team within one working day, without a code change | H | M | The only way to make "configurable enough to absorb change" mean anything |
| QA11 | Referral-system changes are reflected in the platform within 15 minutes | H | M | Makes "frequent synchronisation" a number |
Constraints
| # | Constraint | Bus | Arch | Note |
|---|---|---|---|---|
| C01 | Delivered as a service, hosted and operated by the Supplier | H | H | Places the system outside the customer's network — every integration becomes an external call, with the security and latency consequences that follow |
| C02 | Web UI on currently supported framework versions; exact list agreed at discovery | M | M | Records the vague "current web technologies" line as the constraint it actually is, and defers the specifics honestly |
The utility tree that follows
| QA | Refinement | Scenario | Priority |
|---|---|---|---|
| Performance | Response time | Routine screens respond within 2 s at p95 under normal load | H, H |
| Performance | Response time | Daily reports within 60 s; analytical reports within 10 min | M, M |
| Performance | Geographic latency | Outside the primary region, p95 degrades by no more than 50% | M, H |
| Compliance | Data residency | Patient data remains in the jurisdiction of collection | H, H |
| Security | Transport | All authenticated traffic uses TLS 1.3 or better | M, M |
| Reliability | Availability | Patient and Administration portals 99.9% | M, H |
| Reliability | Availability | Partner portal 99% | M, M |
| Scalability | Capacity | 4,200 concurrent users, absorbing 12% annual growth | H, H |
| Scalability | Extensibility of reach | Two additional regions within three years | M, H |
| Portability | Client reach | Full functionality on phones and tablets | H, H |
| Configurability | Reaction to change | Protocol or policy change applied within one working day, no code change | H, M |
| Deployability | Release impact | No more than 10 minutes of reduced service on promotion | M, M |
| Interoperability | Synchronisation | Referral-system changes reflected within 15 minutes | H, M |
| Maintainability | Operating model | Delivered as a service, hosted by the Supplier | H, H |
Notice the problem this tree exposes: five scenarios came out (H, H). That is not a result, it is a symptom — it means the prioritisation has not really been done. Before choosing tactics, go back to the stakeholders and force the ranking. Here, taking Compliance, Scalability and Performance as the top three is a defensible reading, because data residency is a legal precondition, capacity is a growth precondition, and response time is what every user experiences on every interaction.
Tactics for the top three
| QA and scenario | Tactic | How it applies here |
|---|---|---|
| Compliance — patient data stays in its jurisdiction | Data localisation | Enumerate every jurisdiction the network operates in, including the two planned regions. Select a provider with a regional presence in each |
| Partition by jurisdiction | One patient-data store per region; route at the identity boundary so a request is bound to its region before it touches patient data | |
| Keep the global layer non-identifying | The cross-region index holds only opaque keys and non-identifying attributes, so search and reporting work globally without moving regulated data | |
| Scalability — 4,200 concurrent users, 12% growth | Scale out (X axis) | Stateless application tier behind a load balancer; autoscale on request-queue depth rather than CPU, because the workload is I/O-bound on partner APIs |
| Partition data (Z axis) | Region is already the partition key imposed by the compliance tactic — reuse it rather than inventing a second scheme | |
| Scale up the data tier | Managed database with read replicas serving the reporting and search-indexing paths | |
| Performance — routine screens within 2 s at p95 | Response-time budget | Decompose the 2 s across gateway, application, partner call and data access, and hold each to its share — see the technique in Module 6 |
| Cache with event-driven invalidation | Cache partner availability with a short TTL, invalidated by partner update events rather than waiting for expiry | |
| Separate the read model | Reporting reads a projection, not the transactional store, so a heavy report cannot degrade booking latency |
How each is verified at a release checkpoint
- Compliance — automated test asserting that a request carrying a region-A patient identifier cannot read or write region-B storage; plus an infrastructure audit of store locations
- Scalability — load test to 4,200 concurrent sessions plus 12%, observing that autoscaling engages and p95 holds; confirm scale-in also works, since only scaling out is usually tested
- Performance — synthetic transactions per screen class reporting p95 continuously, with the per-component budget instrumented so a regression identifies which component consumed its share
How ASR extraction goes wrong
These are the failure modes worth rehearsing, because they recur on nearly every engagement.
Copying instead of reformulating. A requirement lifted verbatim from the customer's document inherits its vagueness. If you cannot state the response measure, you have not finished writing the ASR.
Missing the architecturally significant functional requirements. Teams scan for quality attributes and skip the functional list entirely — but integration requirements hide there, and they are the ones that reshape the architecture. "One partner is automated, six hundred are manual" is a functional requirement with more architectural consequence than most of the quality attributes.
Discarding a generic phrase instead of clarifying it. "Highly configurable to support growth" is not usable as written — which makes it a requirement that needs a conversation, not one to drop. Dropping it is how you discover at UAT that configuration was expected to be self-service.
Confusing a testable requirement with a constraint. "One coherent look and feel across every portal" is a requirement you verify; it is not a constraint that removes design freedom. Filing it as a constraint hides it from the test plan.
Confusing interoperability with portability. Interoperability is about the quality of an integration — protocol, format, latency, error semantics. Portability is about running in a different environment. An integration is usually both a functional requirement (we must integrate) and a quality attribute requirement (within 15 minutes, over TLS, with defined failure behaviour).
Offering process measures as architectural tactics. "Ensure the team includes experienced operations engineers" may be sound advice and is not an architectural tactic. A tactic is a design decision about the system. Similarly, "it will be hosted by the supplier" is a constraint that creates quality attribute problems; it does not solve any.
Not separating assumptions from stated requirements. Where you assume a figure because none was given, mark it visibly. Otherwise your assumption is indistinguishable from the customer's commitment, and nobody ever revisits it.
Accepting an availability figure without pricing it. Nines are bought with redundancy, and each nine costs multiples of the last. If you cannot show the cost of an outage hour, you cannot tell whether the number you have been handed is too strict or too lax — which is why Module 6 derives the figure from the business arithmetic instead.
Exercises — Module 3
- Review the provided scenario
- Read the ASR characterisation article in the materials first
- Identify and document only ASRs, not all requirements, split into three sections: Functional, Quality Attributes, Constraints
- Reformulate every ambiguous requirement rather than copying it from the initial document
- Prioritise all identified ASRs on business value and architectural impact, based on understanding of the business context and your experience/assumptions
- Provide a short rationale why you considered each requirement architecturally significant
- Create a utility tree with QA requirements — drawn as SEI recommends, or as a simple table
- Add only QA requirements (optionally constraints) to the utility tree, not functional ASRs
- Add prioritization for each scenario, evaluating from business and architectural points of view (H/M/L)
- Where you make assumptions (e.g. setting availability to 99.9% because no requirement was found), separate them visually using a different font or colour from the real requirements
- Learn tactics from Software Architecture in Practice by SEI and any other sources
- Based on priorities from the utility tree (H,H; H,M; M,H) choose the top-3 quality attributes
- Choose tactics for achieving them, and explain using text or diagrams how you will apply the tactics to this task's context — the main idea is to use the tactics particularly for this solution, not to randomly select them from the SEI book
- Describe approaches that will confirm the attributes are achieved properly at a checkpoint such as the project release
Module 4 — Architectural Styles and Patterns
Style vs pattern vs tactic
There is no single definition and no clear separation between styles and patterns — as usual, everything depends on the usage context.
| Term | Meaning |
|---|---|
| Architectural style | The highest level of granularity in architecture. Specifies layers, high-level modules of the application, how those modules and layers interact, and the relations between them. A general direction for how you plan to build the solution — "we are going to use event-driven design" |
| Architectural pattern | Solves problems related to the architectural style, becoming more specific because it takes the context into account. For example: "what classes will we have and how will they interact in order to implement a system with a specific set of layers", or "what high-level modules will we have in our service-oriented architecture and how will they communicate", or "how many tiers will our client-server architecture have" |
| Architectural tactic | Design decisions that improve individual quality attribute concerns. Tactics implemented in existing architectures can significantly impact the architecture patterns in the system; tactics selected during initial design significantly impact which patterns are used and how they must change to accommodate the tactics |
A design solution for a concrete context and problem is an architectural pattern. A pattern includes or consists of a number of architectural tactics.
Foundational principles
| Principle | Definition |
|---|---|
| Single Responsibility (SRP) | Every object should have a single responsibility, and all its services should be narrowly aligned with that responsibility. At some level cohesion is considered a synonym for SRP |
| Separation of Concerns (SoC) | The process of breaking a program into distinct features that overlap in functionality as little as possible. A concern is any piece of interest or focus in a program; typically concerns are synonymous with features or behaviours |
| Bounded Context | A central pattern in Domain-Driven Design and the focus of DDD's strategic design, which is all about dealing with large models and teams. DDD deals with large models by dividing them into different bounded contexts and being explicit about their interrelationships. A Context Map is the global view of the application as a whole; each bounded context fits within it to show how they should communicate and how data should be shared |
| Principle of Least Knowledge | Any component or object should not have knowledge about the internal details of other components. This avoids interdependency and helps maintainability |
Coupling
A software unit may be of any granularity: methods in a class, classes, subsystems, packages, modules, services, systems. Coupling is the degree of interdependence between software modules. Two tightly coupled modules are strongly dependent on each other; loosely coupled modules are not dependent; uncoupled modules have no interdependence at all. A class with high (strong) coupling relies on many other classes.
Types of coupling, strongest to weakest:
- Classes mutually access each other's private data — a very strong form; you can no longer change one class without considering the other
- Classes communicate via a global data structure — direct dependencies are released and outsourced to the global structure, but coupling is still very strong: all changes affecting the global data also affect all classes working with it
- Classes communicate only via method parameters — considerably lower coupling; the methods involved contain only essential data, so changes cause only local changes to the relevant methods
- No coupling — a system of connected objects communicating via messages
Example: for loosely coupled classes, changing something major in one class should not affect the other. High coupling makes code difficult to change and maintain: because classes are closely knit, a change could require reworking an entire system.
Loose coupling can be achieved by providing an interface other classes use rather than calling a specific implementation directly. When the app calls IDatabase.exportToFile(), you can change the underlying DB from Oracle to MySQL without changing the calling class's code.
A real drawback story from the homework: an application was tightly coupled with a third-party service. Performance testing — and functional testing — was painful, because when the third-party tool was down or experiencing temporary degradation it affected test results. The fix was to talk to an interface and build a stub implementing it.
Cohesion
Cohesion refers to the degree to which the elements inside a module belong together — it measures the strength of relationship between pieces of functionality within a given module. In highly cohesive systems functionality is strongly related. Cohesion is an ordinal measurement, usually described as "high" or "low".
Modules with high cohesion are preferable, because high cohesion is associated with robustness, reliability, reusability and understandability. Low cohesion is associated with being difficult to maintain, test, reuse or even understand.
Low cohesion example: methods in a class doing something totally unrelated to each other — a UTIL class serving as a Swiss army knife providing file export, string operation helpers, FTP connectivity and whatever else. The solution is to separate the helper classes.
Cohesion is the indication of the relationship within a module. Coupling is the indication of the relationships between modules.
Monolith
A monolithic architecture suits simple, lightweight applications for POC or MVP purposes. But one major drawback is tight coupling — over time monolithic components become tightly coupled and entangled, which affects management, scalability and continuous deployment. Other cons stemming from tight coupling:
| Con | Detail |
|---|---|
| Reliability | An error in any of the modules can bring the entire application down |
| Updates | Due to a single large codebase and tight coupling, the entire application must be deployed for each update |
| Technology stack | A monolithic application must use the same technology stack throughout; changes are expensive in both time and cost |
A real drawback story: a desktop application compiled and deployed as one huge executable, used by various departments. Each deployment affected all departments, and there had to be at least core regression testing for every department's functionality after a change in even one particular place.
Layered
One of the powerful features of the layered pattern is the separation of concerns among components.
Rules and their nuances:
- Normally requests always go from up to down. A lower layer should never perform a request to upper layers
- But a layer is allowed to make upward calls as long as it isn't expecting an answer from them — this is how the common error-handling scheme of callbacks works
- Requests from A to C are allowed to bypass B. In that case layer B is considered an open layer, and you take away the benefits of having isolated layers. The Open/Closed principle allows skipping some layers intentionally
- Any set of boxes stacked on top of each other does not constitute a layered architecture. If everyone is allowed to use everything, it is not layered
- The key provides the answer to "what allows to use what"
Onion architecture consists of typical layers, but it is not obvious.
For more depth: search for "layer bridging" in Software Architecture in Practice by SEI, and read chapter 1 of Software Architecture Patterns by Mark Richards.
A pragmatic view from the homework: stick to the classic approach — A talks to B only, B talks to C only — as much as possible. Jumping from A to C might be needed when performance isn't good enough and you need to speed up; that can be a valid trade-off. Talking backwards from C to B is hard to justify and looks like something that could not be called layered architecture at all.
SOA and microservices
Scope is the difference: Service-Oriented Architecture is enterprise scope; microservices architecture is application scope. In SOA, reusability of integrations is the primary goal, and at an enterprise level striving for some level of reuse is essential — reusability and component sharing increase scalability and efficiency.
Microservices are a SOA instantiation driven by DevOps practices, emphasising CI/CD: smaller services, smaller responsibilities, less coupling — more infrastructure mess.
Nine characteristics:
- Component-based architecture — components are good again because of low coupling, independent deployment and scalability
- The monolith is split according to business functions, not according to organisational structure
- Treat software not as work to do and hand out to maintenance, but as a product to be developed over its lifetime — this emphasises business value for users
- Simple communication with no logic — no complex routing or transformation as in an ESB — plus a smart service that contains the logic inside
- In microservices you can take advantage of the different tools and approaches that better fit a task. Responsibility is distributed as well, and this impacts quality
- Instead of an org-structure- and vendor-licensing-driven approach to storing data, microservices use separate DBs per service — polyglot persistence — which is more efficient because you use the proper technology for a task
- Extensive use of automated infrastructure platforms (e.g. AWS) for both deployment and operations
- Design software tolerant to failures as much as possible — monitor, restore
- Promotes making changes and evolving the system, since you can touch a component with no impact on other components
A reference microservices layering:
| Layer | Contents |
|---|---|
| Consumer | Shows the different clients of the product |
| Delivery | Balances requests, caches static web content, addresses requests to the right application |
| Aggregation | Server-side UI application, and different sets of APIs for specific clients which aggregate business services |
| Service | Business services, system services, gateway and discovery services |
| API Gateway & Service Discovery | Internal components providing routing, discovery, balancing and security for the service layer |
| Business Microservices | Implement business logic and processes |
| System Services | Existing services in the customer's environment — LDAP, printing service, email server, time service |
| Platform Services | Provide support for security and microservices management |
| Infrastructure | Provides virtual infrastructure for the platform |
A microservice is an architecture that structures the application as a set of loosely coupled, collaborating services.
Challenges and drawbacks. It can be very hard for a small company to maintain the whole lifecycle, because it requires extra methods and tools to support the development process — you need DevOps tools such as CI/CD servers, configuration management platforms and APM tools to manage the network. An additional drawback is performance: sending messages back and forth between microservices comes with a certain overhead. The most challenging part is finding how to partition the solution. Orchestrating numerous development teams is also more difficult.
Event-driven architecture
The event-driven pattern is a popular distributed asynchronous architecture pattern used to produce highly scalable applications. It is also highly adaptable and can be used for small applications as well as large complex ones. It is made up of highly decoupled, single-purpose event-processing components that asynchronously receive and process events.
Use it when you want to achieve a highly decoupled, asynchronous and distributed architecture. Once you achieve a high degree of decoupling you can scale architecture components independently, which makes it a good option for modern, distributed, cloud-enabled applications that are horizontally scalable and resilient to failure.
Most often just a part of a system — some sub-system or component — is implemented according to the event-driven style.
Rendering diagram…
Mediator topology — commonly used when you need to orchestrate multiple steps within an event through a central mediator. It is useful for events that have multiple steps and require some level of orchestration to process.
Four main component types: event queues, an event mediator, event channels, and event processors. The flow starts with a client sending an event to an event queue, which transports it to the mediator. The mediator receives the initial event and orchestrates it by sending additional asynchronous events to event channels to execute each step of the process. Event processors listen on the channels, receive the event from the mediator, and execute specific business logic.
- The event-mediator component is responsible for orchestrating the steps contained within the initial event
- Event channels are used by the mediator to asynchronously pass processing events related to each step to the processors; channels can be message queues or message topics
- Event processor components contain the application business logic necessary to process the processing event
The event mediator can be implemented in a variety of ways, and as an architect you should understand each option to ensure the solution matches your needs.
Broker topology — differs in that there is no central event mediator; instead the message flow is distributed across the event processor components in a chain-like fashion through a lightweight message broker (ActiveMQ, HornetQ). Useful when you have a relatively simple event processing flow and do not want or need central event orchestration. Each event-processor component is responsible for processing an event and publishing a new event indicating the action it just performed. Channels within the broker can be message queues, message topics, or a combination.
Related: the Actor model is also covered as an event-based approach.
REST and the Richardson Maturity Model
Level 3 of the model is hypermedia controls. It is worth reaching when the client doesn't know the full REST API specification, or when the client's behaviour depends on internal logic implemented inside the REST service.
Example: when a client GETs an account balance it also receives a list of possible actions as links. Per the service's internal logic, when the balance is negative the only available action is "deposit money"; otherwise deposit, withdraw and close are offered. The client may also change UI elements accordingly, disabling or hiding buttons.
A big advantage of RESTful APIs that have attained level 3 is the ability to layer and apply cache constraints. Hypermedia helps customise content for new environments while retaining UX across the board: by including unique URLs within a response package, hypermedia APIs tell clients what capabilities are possible and in what scenarios. Hypermedia links can immediately reflect new user permissions without breaking changes on the client side. Hypermedia is a way for APIs to respond to next-generation platforms and the new issues that arise — beneficial in messaging applications such as Slack.
CQRS
Traditional CRUD disadvantages:
- It often means a mismatch between the read and write representations of the data, such as additional columns or properties that must be updated correctly even though they aren't required as part of an operation
- It risks data contention when records are locked in a collaborative domain where multiple actors operate in parallel on the same data, or update conflicts caused by concurrent updates under optimistic locking. These risks increase as complexity and throughput grow. The traditional approach can also negatively affect performance due to load on the data store and data access layer, and the complexity of queries required
- It can make managing security and permissions more complex, because each entity is subject to both read and write operations, which might expose data in the wrong context
When CQRS suits. Very useful in the case of large differences between the numbers of read and write operations — social networks, for instance. You can scale both sides independently to achieve better I/O performance and support parallel operations on the same datasets. Even without a big disparity, you can apply different optimization strategies to the two sides — for example using different database access techniques for read and update. It is particularly relevant for handling high-performance applications, and for writing normalized data very quickly then denormalizing it so reads read prepared data with no need to join multiple tables.
Considerations before implementing:
- Dividing the data store into separate physical stores for read and write can increase performance and security, but adds complexity in resiliency and eventual consistency. The read store must be updated to reflect changes to the write store, and it can be difficult to detect when a user has issued a request based on stale read data — meaning the operation can't be completed
- Apply CQRS to limited sections of your system where it will be most valuable
- A typical approach to deploying eventual consistency is to use event sourcing in conjunction with CQRS, so the write model is an append-only stream of events driven by command execution, and those events update materialized views acting as the read model
Not recommended for implementation across the whole system. There are specific components of an overall data management scenario where CQRS is useful, but it adds considerable and unnecessary complexity when not required. Be aware it can be complex to implement and provides eventual consistency only.
Event sourcing
Events are immutable and can be stored using an append-only operation. The user interface, workflow or process that initiated an event can continue, and tasks handling the events can run in the background. Combined with the fact that there is no contention during the processing of transactions, this can vastly improve performance and scalability, especially for the presentation level.
Events are simple objects describing an action that occurred together with any associated data required. They don't directly update a data store — they're simply recorded for handling at the appropriate time, which simplifies implementation and management.
Events typically have meaning for a domain expert, whereas object-relational impedance mismatch can make complex database tables hard to understand: tables are artificial constructs representing the current state of the system, not the events that occurred.
Event sourcing can help prevent concurrent updates from causing conflicts because it avoids directly updating objects in the data store. However the domain model must still be designed to protect itself from requests that might result in an inconsistent state.
The append-only storage provides an audit trail usable to monitor actions taken against a data store, regenerate the current state as materialized views or projections by replaying the events at any time, and assist in testing and debugging. The requirement to use compensating events to cancel changes provides a history of changes that were reversed — which wouldn't be the case if the model simply stored current state. The list of events can also analyse application performance, detect user behaviour trends, or obtain other useful business information.
The event store raises events and tasks perform operations in response. This decoupling of the tasks from the events provides flexibility and extensibility: tasks know about the type of event and the event data, but not about the operation that triggered the event, and multiple tasks can handle each event. This enables easy integration with other services and systems that only listen for new events raised by the event store. However, event sourcing events tend to be very low level, and it might be necessary to generate specific integration events instead.
When to use it:
- When you want to capture intent, purpose or reason in the data — changes to a customer entity captured as specific event types such as Moved home, Closed account, or Deceased
- When it's vital to minimize or completely avoid conflicting updates to data
- When you want to record events and be able to replay them to restore state, roll back changes, or keep a history and audit log — for example when a task involves multiple steps and you need to revert updates then replay some steps to bring data back to a consistent state
- When using events is a natural feature of the application's operation and requires little additional development effort
- When you need to decouple the process of inputting or updating data from the tasks required to apply those actions — to improve UI performance, or to distribute events to other listeners. For example, integrating a payroll system with an expense submission website, so events raised by the event store in response to website updates are consumed by both the website and the payroll system
- When you want flexibility to change the format of materialized models and entity data if requirements change; or — with CQRS — when you need to adapt a read model or the views exposing the data
- When used with CQRS and eventual consistency is acceptable while the read model updates, or the performance impact of rehydrating entities from an event stream is acceptable
Sharding strategies
| Strategy | Trade-offs |
|---|---|
| Lookup | Offers more control over how shards are configured and used. Using virtual shards reduces the impact when rebalancing data, because new physical partitions can be added to even out the workload — and the mapping between a virtual shard and the physical partitions implementing it can be modified without affecting application code that uses a shard key. Looking up shard locations can impose additional overhead |
| Range | Easy to implement and works well with range queries, because they can often fetch multiple data items from a single shard in a single operation. Offers easier data management — if users in the same region are in the same shard, updates can be scheduled per time zone based on local load and demand. However it doesn't provide optimal balancing between shards; rebalancing is difficult and might not resolve uneven load if the majority of activity is for adjacent shard keys |
| Hash | Offers a better chance of even data and load distribution. Request routing can be accomplished directly using the hash function — there's no need to maintain a map. Computing the hash might impose additional overhead, and rebalancing shards is difficult |
Fault tolerance patterns
There are many fault-tolerant patterns covering all the stages of the error lifecycle; the course reviews a subset. The reference is Patterns for Fault Tolerant Software.
Three types of redundancy
| Type | Description |
|---|---|
| Spatial | The system has multiple copies in different places that are redundant, providing alternatives selectable with minimal unavailability. Easy to understand and visualize in terms of hardware — multiple copies of the hardware platform |
| Temporal | Redundancy that occurs over time, which helps achieve correct results but lengthens the time of unavailability. Recovery Blocks provide temporal software redundancy: a program consists of a primary block and secondary blocks; if the primary's result fails its acceptance test, the secondary blocks execute in sequence until a result passes. Recovery blocks offer primarily temporal redundancy because they execute sequentially |
| Informational | When information is repeated it can aid detection and correction. Provided by having multiple versions of the same data available, which can be stored in different places on different types of storage — for example disk and flash memory |
Spatial redundancy methods
| Method | Description |
|---|---|
| Active-Active | Provides totally redundant units of mitigation for the critical functionality. At any given time both elements are active and load sharing, and either is capable of processing the entire load. Provides the fastest recovery, but has a high cost because there is much more capability in the system than the ordinary workload needs. Implies a pairing between the two active units |
| Active-Standby | The standby is again paired with an active element, but the standby element is not performing useful work. This means the same amount of resources is needed as in active-active, but during normal operation the standby is idle |
| N+M | Where a one-to-one relationship is too expensive: N active elements process the workload and M redundant standby elements are ready to assume control when a failure occurs in any of the N |
The choice of redundancy regime has great effect on switching speed. If the redundant elements are hot standbys, switchover occurs very quickly with minimal outage of the main application. If the standby is only warm, it requires time to return to the same application state — checkpoints help get there more quickly. When the standby is cold, it must be started from an inactive state, which adds time; after starting it can be treated as a warm standby.
Related material covered: voting algorithms and triple modular redundancy.
Bulkhead
When to use: isolate resources used to consume a set of backend services, especially if the application can provide some level of functionality even when one of the services is not responding; isolate critical consumers from standard consumers; protect the application from cascading failures.
May not be suitable when: less efficient use of resources is not acceptable in the project, or the added complexity is not necessary.
Circuit breaker
Prevents an application from repeatedly trying to execute an operation that's likely to fail, allowing it to continue without waiting for the fault to be fixed or wasting CPU cycles determining that the fault is long-lasting. Fail fast!
It is a kind of proxy between the calling service and the called service, detecting whether the called service is in trouble — responses timing out or errors returned. When a threshold is exceeded the breaker changes state, preventing the caller from spending time and resources on calls unlikely to succeed anyway. The breaker must also be capable of detecting when the called service is up again, so it's fine to talk to it.
Use this pattern to prevent an application from trying to invoke a remote service or access a shared resource if the operation is highly likely to fail.
Security patterns
Federated identity
Using different credentials for multiple applications can:
- Cause a disjointed user experience — users often forget sign-in credentials when they have many different ones
- Expose security vulnerabilities — when a user leaves the company the account must immediately be deprovisioned, and it's easy to overlook this in large organizations
- Complicate user management — administrators must manage credentials for all users and perform additional tasks such as providing password reminders
When to use:
- Single sign-on in the enterprise — authenticate employees for corporate applications hosted in the cloud outside the corporate security boundary without requiring them to sign in every time. The experience matches on-premises applications, where they authenticate on signing in to the corporate network and thereafter have access to all relevant applications
- Federated identity with multiple partners — authenticate both corporate employees and business partners who don't have accounts in the corporate directory. Common in B2B applications, applications integrating with third-party services, and where companies with different IT systems have merged or shared resources
- Federated identity in SaaS applications — independent software vendors provide a ready-to-use service for multiple clients or tenants, each authenticating using a suitable identity provider. Business users use corporate credentials while consumers and clients of the tenant use social identity credentials
Might not be useful when: all users can be authenticated by one identity provider and there's no requirement to authenticate with another — typical in business applications using a corporate directory accessible within the application, via a VPN, or through a virtual network connection between the on-premises directory and the application. Also when the application was originally built with a different authentication mechanism, perhaps with custom user stores, or lacks the capability to handle the negotiation standards used by claims-based technologies — retrofitting claims-based authentication and access control into existing applications can be complex and probably not cost effective.
Gatekeeper
| Benefit | Detail |
|---|---|
| Controlled validation | The gatekeeper validates all requests and rejects those that don't meet validation requirements |
| Limited risk and exposure | The gatekeeper doesn't have access to the credentials or keys used by the trusted host to access storage and services. If the gatekeeper is compromised, the attacker doesn't get access to these credentials or keys |
| Appropriate security | The gatekeeper runs in a limited privilege mode while the rest of the application runs in the full trust mode required to access storage and services. If compromised, it can't directly access the application services or data |
Useful for: applications handling sensitive information, exposing services that must have a high degree of protection from malicious attacks, or performing mission-critical operations that shouldn't be disrupted; and distributed applications where it's necessary to perform request validation separately from the main tasks, or to centralize validation to simplify maintenance and administration.
Valet key
Useful when:
- To minimize resource loading and maximize performance and scalability — a valet key doesn't require the resource to be locked, no remote server call is required, there's no limit on the number of keys that can be issued, and it avoids a single point of failure resulting from performing the data transfer through application code. Creating a valet key is typically a simple cryptographic operation of signing a string with a key
- To minimize operational cost — enabling direct access to stores and queues is resource and cost efficient, can result in fewer network round trips, and might allow a reduction in the number of compute resources required
- When clients regularly upload or download data, particularly where there's a large volume or each operation involves large files
- When the application has limited compute resources available due to hosting limitations or cost. The pattern is even more helpful with many concurrent uploads or downloads, because it relieves the application from handling the transfer
- When data is stored in a remote data store or a different datacenter. If the application acted as a gatekeeper there might be a charge for the additional bandwidth of transferring data between datacenters, or across public or private networks between client, application and data store
Might not be useful when:
- The application must perform some task on the data before it's stored or sent — validation, logging access, or executing a transformation. However some data stores and clients can negotiate and carry out simple transformations such as compression and decompression (a web browser can usually handle GZip)
- The design of an existing application makes it difficult to incorporate the pattern — using it typically requires a different architectural approach for delivering and receiving data
- It's necessary to maintain audit trails or control the number of times a data transfer operation is executed, and the valet key mechanism in use doesn't support notifications the server can use to manage these operations
- It's necessary to limit the size of the data, especially during upload. The only solution is for the application to check the data size after the operation completes, or check the size of uploads after a specified period or on a scheduled basis
Zero-downtime deployment
It is essential to be able to roll back a deployment in case it goes wrong. Debugging problems in a running production environment is almost certain to result in late nights, mistakes with unfortunate consequences, and angry users. You need a way to restore service to your users when things go wrong, so you can debug the failure in the comfort of normal working hours.
Several rollback methods exist; the more advanced techniques — blue-green deployments and canary releasing — can also be used to perform zero-downtime releases and rollbacks.
Blue-green deployment. The idea is to have two identical versions of your production environment — blue and green. Users of the system are routed to the green environment, which is the currently designated production. In some situations these can be different pieces of hardware, or different virtual machines running on the same or different hardware; they can also be a single operating environment partitioned into separate zones with separate IP addresses for the two slices.
Canary release. It is usually a safe assumption that you only have one version of your software in production at a time. If you have an extremely large production environment it's impossible to create a meaningful capacity testing environment, unless your application's architecture employs end-to-end sharding. So how do you ensure a new version won't perform poorly?
Like blue-green, you initially deploy the new version to a set of servers where no users are routed. You can then do smoke tests and, if desired, capacity tests on the new version.
There are different strategies for choosing which users see the new version: a simple strategy is a random sample; some companies release to their internal users and employees before releasing to the world; a more sophisticated approach chooses users based on their profile and other demographics. You can even have multiple versions of your application in production at the same time, routing different groups of users to different versions as required.
Benefits:
- It makes rolling back easy — just stop routing users to the bad version and investigate the problem
- You can use it for A/B testing by routing some users to the new version and some to the old
- You can check whether the application meets capacity requirements by gradually ramping up the load, slowly routing more and more users while measuring response time and metrics like CPU usage, I/O and memory
Constraints:
- Hard to use where users have your software installed on their own computers or mobile devices
- Any shared resource needs to work with all versions of the application you want in production
- Supporting multiple versions is painful, so keep the number of canaries to a minimum
If your goal is zero downtime and your application has very low automated test coverage, canary release is the technique. In an extremely large production environment it's impossible to create a meaningful capacity testing environment, and a benefit of canary releases is the ability to do capacity testing of the new version in a production environment with a safe rollback strategy if issues are found. It lets you test on a small portion of users first, which is the least painful way to check functionality in the absence of auto-tests — though you still need a toolset for monitoring what's happening to users on the new version.
Integration
Enterprise Integration Patterns is the "bible" of the integration patterns — a must read. Concepts from the book are widely used in modern platforms, frameworks and tools.
Delivery model selection
The homework scenario: you are the chief architect of a healthcare startup whose clients are large and medium-sized medical organisations worldwide with 100k+ patients. The idea is to provide clients with a configurable web interface to manage their data — patients and their medical details and history — and to share the part of the data that is not private according to regulation policies across all clients. Which delivery model: IaaS, PaaS or SaaS?
SaaS. It allows the company to concentrate on the business side rather than the technical. Vendors providing the SaaS platform usually provide full maintenance and update/upgrade services included in the subscription. Applications built on SaaS platforms are scalable and highly available and provide built-in functionality for data sharing across regions and clients. SaaS also lets you build application logic letting customers manage what to share and what not to. IaaS is out of consideration; PaaS would mean providing a platform for each customer to build their own solution upon, which is less attractive to the customer than out-of-the-box functionality.
Exercises — Module 4
Try answering based on your own vision and knowledge first; if that does not work, research and learn the topic. Answers go straight into the document.
- How do we call a design solution for a concrete context and problem — Architectural Style, Architectural Pattern or Architectural Tactic? Explain how you understand the difference between these terms
- Explain how you understand 'coupling' and 'cohesion', supporting your explanation with specific examples
- What are the typical cons of the Monolith architectural style? Share real drawbacks of using monoliths from your experience
- Given the layer diagram: is it correct layered architecture and why? Is it possible for C to use B? For A to use C?
- Explain when it is worth using the Event-driven style. When would you apply the Mediator topology and when the Broker topology?
- When using REST, is it worth trying to reach Level 3 of the Richardson maturity model? Describe a case where it could be beneficial
- Explain how you understand the term "microservice". List challenges and possible drawbacks
- Describe some cases where the CQRS pattern would be suitable
- Find one or more integration frameworks or platforms in your domain language and describe their pros and cons briefly
- Having the fault-tolerance definitions 'Error', 'Fault', 'Failure', what should be their order — which leads to another? Provide samples of each from your current project
- Describe cases when using the Circuit breaker pattern would be beneficial
- If your goal was zero downtime and your application had very low automated test coverage, which techniques would you select and why?
- As Chief Architect of a global healthcare startup, which software delivery model would you choose — IaaS, PaaS or SaaS? Add the rationale
Module 5 — Architecture Modeling
Opening questions worth asking yourself: how often do you create diagrams and do modelling? What kinds of diagrams do you create? What tools do you use?
Notation formality
Three main categories of notation, shown as a pyramid representing usage and popularity:
| Category | Examples | Character |
|---|---|---|
| Informal | Boxes and lines | Widest usage |
| Semi-formal | UML, BPMN, ArchiMate | Middle |
| Formal | AADL — e.g. the graphical definition of a speed control system | Narrowest |
A diagram without a key makes it genuinely difficult to identify the different elements. The course demonstrates this deliberately with a keyless diagram for discussion. Always provide a legend.
UML
The UML specification is updated and managed by the Object Management Group. The first versions were created by the "Three Amigos" — Grady Booch (creator of the Booch method), Ivar Jacobson (Object-Oriented Software Engineering, OOSE), and Jim Rumbaugh (Object-Modeling Technique, OMT).
| Version | Date | Change |
|---|---|---|
| 1.3 | 03-2000 | A number of changes to the UML metamodel, semantics and notation, but considered a minor upgrade to the original proposal |
| 1.4.2 | 01-2005 | Accepted as ISO specification ISO/IEC 19501. (UML 1.5 was released two years earlier) |
| 2.0 | 08-2005 | New diagrams: object, package, composite structure, interaction overview, timing, profile. Collaboration diagrams renamed communication diagrams |
| 2.5 | 06-2015 | Called a "minor revision" to UML 2.4.1, but a lot of effort went into simplifying and reorganizing the specification document, which was re-written "to make it easier to read" — for example reducing forward references as much as possible |
Popularity of UML is decreasing. The top three diagrams in practice: class, sequence, use case.
Today, when UML notation is not so widely used due to objective reasons, we can use the "boxes and lines" notation for any view.
BPMN, ArchiMate and behavioural diagrams
BPMN is semi-formal. Beyond the standard diagram set:
- Conversation diagrams — represent groups of messages called "communications" and their relation between process and participants
- Choreography diagrams — represent participant interaction between task and users or resources, and the messages resulting from this interaction
- Swim lanes are partitioned
ArchiMate is a semi-formal enterprise architecture modelling language.
There are also many similar diagrams for behaviour and state: UML Activity, Data flow, UML State, BPMN.
Diagram hygiene
When tidying up a diagram, think about:
- Aligning elements — either by one of their sides (e.g. top) or by their centres; the latter works best when aligning vertically
- Making elements the same size where possible
- Always including a key
Exercises — Module 5
No separate assignment; modelling is exercised through the Module 6 documentation homework and the architecture katas embedded in the sessions.
Module 6 — Architecture Documentation
Worth asking before you start: do you find architecture documentation useful — and if not, why? Are you sceptical about documentation?
Forms of documentation
| Form | Examples |
|---|---|
| Formal document | Usually quite big and complete documents: RFP Response, Software Architecture Document, Architecture Definition Document, Architecture Design, Architecture and Code Review |
| Articles and guidelines | Design guidelines, implementation guidelines, design of particular cases. Also a good example: when big formal documentation is split into a group of articles and guidelines |
| Presentations | Often used in pre-sales and for presenting architecture design to business stakeholders and teams |
| Models and diagrams | Design models and various forms of diagrams |
| Autogenerated documentation | Based on metadata or implementation — API documentation, SDK documentation |
Cost and the three attributes
Architecture documentation should be reasonable, and the amount of documentation should be reasonable — but it is almost impossible to calculate this value because of the big variety of every parameter and the difficulty of making predictions. In reality you select it based on your personal experience.
Total Cost of Ownership (TCO) includes the initial costs to implement a project together with the continuing costs to maintain, modify, train staff, house, deploy, provide infrastructure, or any other cost associated with the project — including final decommissioning. TCO is an estimate including all direct and indirect costs over the useful life of the application, commonly used in full cost accounting systems.
Three main attributes of good documentation:
| Attribute | Meaning |
|---|---|
| Essential | Select the most essential and important part of your system to document, rather than creating detailed documentation for every small piece. Too detailed documentation could become outdated quite quickly and requires more time to develop |
| Valuable | Understand your stakeholders, and the value of your documentation for them |
| Timely | And evolutionary — you do not need to do big up-front design |
Why views
Software is complex, the design of software is even more complex, and you could not represent your system with one holistic view. Therefore views are the essential part of describing software.
What this basically means is that we handle hundreds of elements, hundreds of element types, their relationships and properties. Views help limit that to a reasonable amount that could fit in our heads.
Principle: it is not possible to capture the functional features and quality properties of a complex system in a single comprehensible model that is understandable by, and of value to, all stakeholders.
Three different perspectives to consider:
- Perspective from stakeholders' points of view — sponsor, PM, dev, devops
- Perspective from a details point of view — conceptual, logical, physical
- Perspective from a domain point of view — data, application, technology
A short history of architectural views
| Year | Who | Contribution |
|---|---|---|
| 1974 | David Parnas | In On a buzzword: hierarchical structures he defined that software is composed of many structures |
| 1992 | Perry and Wolf | Foundation Study of Software Architecture — outlined that architecture involves multiple views and multiple architecture styles; made a comparison with building architecture |
| 1995 | Philippe Kruchten (Rational Software Corporation) | An influential paper describing four main views of software architecture — logical, process, development, physical — plus a distinguished fifth view tying the other four together by showing how they satisfy key use cases: the "4+1" approach. Since embraced as a foundation piece of the Rational Unified Process |
| 1995 | Dilip Soni, Robert Nord, Christine Hofmeister (Siemens Corporate Research) | A similar observation from industrial practice: the conceptual view, module interconnection view, execution view and code view. These correspond more or less to Kruchten's four and became known as the Siemens Four View model |
| 2000 | IEEE | Adopted IEEE 1471-2000 for architecture descriptions. Unlike approaches prescribing a fixed set of views, this standard advocates creating your own views that best serve the stakeholders and their concerns. (The Views and Beyond approach also advises flexibility in choosing your view set) |
| 2005 | Rozanski and Woods | Software Systems Architecture advocates using functional, information, concurrency, development, deployment and operational views |
| — | Philips Research | The CAFCR model, calling for five views: customer, application, functional, conceptual and realization |
Kruchten's 4+1
Rendering diagram…
| View | Content |
|---|---|
| Logical | The most misunderstood of the four. It is essentially a functional decomposition, and it can be drawn several ways: sub-systems; domains and domain entities; states and the transitions between them; business interactions. For the Lumen case it would be functional modules such as referral intake, availability search, offer and confirmation, notifications, partner management and reporting. The logical view primarily serves the functional requirements — what the system offers its users |
| Process | Basically represents abstractions from the logical view within runtime: components, processes, threads, runtime element interactions. It also shows integration with external systems and interfaces to the outside. Addresses concurrency, distribution, integrators, performance, scalability |
| Development | Describes the static organization of the software in its development environment |
| Physical | Deployment onto infrastructure. For Lumen: TLS termination at an edge load balancer, then two or more symmetric application nodes per region — each running the portal front end, the offer-and-confirmation service and the notification worker — connecting to a regional managed database with read replicas, plus a regional search cluster. Drawn per region, because data residency makes the topology repeat rather than centralise |
| +1 Scenarios | Ties the other four together by showing how they satisfy key use cases |
The original description of the model is The "4+1" View Model of Software Architecture, 1995.
The C4 model
The C4 model was proposed by Simon Brown as a simplified model providing great traceability from architecture design to implementation.
Rendering diagram…
In order to create these maps of your code, you first need a common set of abstractions to create a ubiquitous language you can use to describe the static structure of a software system. It means that for your concrete project you need to define what elements you use, and what the meaning of these elements is — what the exact meaning of a container is, what container types you can have, what you call a component, and so on.
The course teaches C4 critically, using a financial risk system as the worked example:
A global investment bank based in London, New York and Singapore trades — buys and sells — financial products with other banks ("counterparties"). When share prices on the stock markets move up or down, the bank either makes money or loses it. At the end of the working day the bank needs to gain a view of how much risk of losing money it is exposed to, by running calculations on the data held about its trades. The bank has an existing Trade Data System (TDS) and Reference Data System (RDS) but needs a new Risk System.
Do you see any issues with the Context diagram?
- No key or legend
- All external elements are represented as "Software Systems", which is really generic — they could be particular systems, like Microsoft Exchange
- Arrows are not always clear: what is the type of communication, what is the API provided by external systems? Only email message and SNMP are mentioned
Do you see any issues with the Container diagram? It provides the next level of detail through technology choices and by showing runtime components, with developers and operations (devops) as primary stakeholders. But:
- Too early for technology choice
- There is no mapping of functional/non-functional requirements to containers
- Difficult to use this approach with a complex solution
The Component diagram for the batch process has the same issues as the previous.
SEI Views and Beyond
View-based documentation allows us to split the bigger task of architecture description into a few smaller ones that are much more manageable. SEI bases its documentation approach on the style-and-view relation.
How to describe a view
| Section | Content |
|---|---|
| Primary Presentation | Shows elements and their relations. It is the main representation of the view, typically a graphical representation |
| Element Catalog | Describes the elements from the primary presentation. It can include the catalog of elements and their properties: element catalog, element properties, element interfaces/APIs, element interaction and relationships |
| Context Diagram | Depicts the relationship with external systems and other environments |
| Variability Guide | Shows possible variability points |
| Rationale | A justification of the design — why this particular design was selected |
Style and view catalogue
Module styles and views cover the structure of implementation units.
| View | Notations and tools taught |
|---|---|
| Decomposition | Box-and-line; UML; treemap (jArchitect for Java, NDepend for C#); jigsaw treemaps (D3.js); Code City — create or generate an MSE file then visualize |
| Uses | UML packages plus UML depends-on arrows; dependency graph. Be aware of different dependencies — up-stream and down-stream |
| Layered | What allows to use what? The key provides the answer. Onion architecture consists of typical layers, but it is not obvious |
| Data model | ERD using Crow's Foot notation; UML |
Modelling non-relational storage — the course explicitly asks "do you have any idea how to model other storages?":
- Key-value — tables are the simplest way, clear and easy to support. Depending on your key you could use different approaches, even JSON. Values differ: blobs → tables; aggregates → JSON; lists → their own treatment
- Document-oriented — JSON and JSON visualization; models with "include" relationships (ERD, UML); vendor-specific tools such as MongoDB Compass
- Column-families — modelling columns and super-columns; the same tools can be used; vendor-specific tools such as the Kashlev Data Modeler for Cassandra, which builds a conceptual model using Chen notation plus access patterns, then generates the logical model based on those access patterns
- Graph database — mind maps?
Component-and-connector styles and views usually explain:
- What the major executing components are and how they interact
- What the major data storage is
- How data flows through the system
- How it could be scaled
There are many C&C styles; SEI specifies dataflow style, call-return style, event-based style, and repository. The concrete C&C views taught: monolith, service-oriented, and event-driven — including ESB and actor-based variants.
Allocation styles and views — deployment above all.
Rozanski and Woods: views, viewpoints and perspectives
A viewpoint defines the stakeholders whose concerns it reflects, and guides principles and template models to construct and format views.
The relationship between views and viewpoints is something like the relationship between classes and objects in programming: class definitions provide templates to construct objects.
A perspective is a collection of architectural activities, tactics and guidelines used to ensure that the system exhibits a particular set of related quality properties.
Each view is directed by its viewpoint — its template and guidance. While a view describes the architecture, perspectives guide us through the process of analyzing and modifying the architecture to ensure it achieves the qualities defined.
Perspectives don't exist in isolation, in contrast to views. Perspectives are worth something only in the context of a particular view — this is called applying the perspective to the view. Applying a perspective doesn't result in new views (there is no "security view" or "scalability view"); it identifies a number of modifications to existing views, to help those views address the stakeholders' quality attribute concerns.
The design loop: having a set of architecture candidates captured as a set of architecture views, you apply perspectives one by one — conducting dedicated activities, identifying action items, choosing and applying tactics. As a result you typically make some changes to the candidate, and so on.
The seven core viewpoints
There are seven core viewpoints for information systems architecture. Although largely disjoint, it is convenient to group them:
Rendering diagram…
| Viewpoint | Describes |
|---|---|
| Context | The relationships, dependencies and interactions between the system and its environment — the people, systems and external entities with which it interacts. Placed at the top to indicate its role as the overarching viewpoint that informs the scope and content of all the others |
| Functional | The system's runtime functional elements, their responsibilities, interfaces and primary interactions |
| Information | The way the system stores, manipulates, manages and distributes information |
| Concurrency | The concurrency structure of the system, mapping functional elements to concurrency units to clearly identify the parts that can execute concurrently and how this is coordinated and controlled |
| Development | Exists to support the system's construction — the software development process |
| Deployment | The environment into which the system will be deployed and the dependencies the system has on elements of it. Captures the hardware environment needed (processing nodes, network interconnections, disk storage facilities), the technical environment requirements for each element, and the mapping of the software elements to the runtime environment that will execute them |
| Operational | How the system will be operated, administered and supported when running in its production environment |
The Functional, Information and Concurrency viewpoints characterize the fundamental organization of the system, and are grouped together to highlight that between them they define how the system provides its functionality.
The viewpoints on the right-hand side are to some extent driven by those on the left — for example the Development viewpoint defines standards and models for the construction of the architecture's functional, information and concurrency elements.
Perspectives
Perspectives deliberately pair tightly related qualities:
- Performance & Scalability Perspective joins two qualities because of the tight relationship between them: performance concerns what workload the system can process and how quickly, whereas scalability focuses on the predictability of system performance as the workload increases
- Availability & Resilience Perspective — the desired quality is to be fully or partially operational as and when required, and to effectively handle failures that could affect system availability
The conceptual model
An architecture is documented in an architectural description (AD).
- The AD consists of one or more views of the architecture. It may also include other elements such as principles, standards and glossaries, which lay the architectural foundations. For example an AD may include a Functional view, a Concurrency view and a Deployment view
- The contents of each view are based on a viewpoint. For example, the contents of an Operational view are based on the templates, patterns and guidelines in the Operational viewpoint
- Each view consists of one or more models. A model is a way to represent some of the salient features of an architecture pertaining to the view. For example, an Information view may include an entity-relationship model, a data ownership model and a state transition model
- Applying a perspective may lead to changes to existing models, or to the creation of one or more secondary architectural models that allow better understanding of the architecture's ability to exhibit a particular quality property — models that do not define one of the system's structures. For example, applying the Security perspective usually involves the creation of a threat model to understand the security threats the system faces
Why models are important: the key skill the model builder uses is abstraction — the process of suppressing unnecessary detail. By removing such detail from our models we allow our stakeholders and ourselves to focus on the most important aspects of our architecture. A good model can help stakeholders understand an architecture they might not understand otherwise.
Benefits and pitfalls of multiple views
Benefits
| Benefit | Explanation |
|---|---|
| Separation of concerns | Describing many aspects of the system via a single representation can confuse communication and, more seriously, can result in independent aspects of the system becoming mixed in the model. Separating different models into distinct but related descriptions helps design, analysis and communication by allowing you to focus on each aspect separately |
| Communication with stakeholder groups | The concerns of each stakeholder group are typically quite different — contrast the primary concerns of end users, security auditors and help-desk staff — and communicating effectively with all of them is a challenge. The viewpoint-oriented approach helps considerably: groups can be guided quickly to different parts of the AD based on their concerns, and each view can be presented using language and notation appropriate to the knowledge, expertise and concerns of the intended readership |
| Management of complexity | Dealing simultaneously with all aspects of a large system can result in overwhelming complexity that no one person can possibly handle. By treating each significant aspect separately the architect can focus on each in turn, helping conquer the complexity resulting from their combination |
| Improved developer focus | The AD is particularly important for developers because they use it as the foundation of the system design. By separating out into different views those aspects particularly important to the development team, you help ensure the right system gets built |
Pitfalls
| Pitfall | Explanation |
|---|---|
| Inconsistency | Using a number of views to describe a system inevitably brings consistency problems. It is theoretically possible to use architecture description languages to create the models and then cross-check them automatically, but there are no such machine-checkable architecture description languages in widespread use today — so achieving cross-view consistency within an AD is an inherently manual process |
| Selection of the wrong set of views | It is not always obvious which set of views suits a particular system. This is influenced by the nature and complexity of the architecture, the skills and experience of the stakeholders and of the architect, and the time available to produce the AD. There really isn't an easy answer other than your own experience and skill and an analysis of the most important concerns |
| Fragmentation | Having several views can make the AD difficult to understand, and each separate view involves significant effort to create and maintain. To avoid fragmentation and minimize overhead, eliminate views that do not address significant concerns. In some cases consider creating hybrid views combining models from a number of views — a combined deployment-and-concurrency view, for example. Beware, however, of combined views becoming difficult to understand and maintain because they address a combination of concerns |
Selecting which views to write
The SEI method is mechanical and worth copying: interview stakeholders to understand their needs, views and concerns — bearing in mind many stakeholders will say they want everything — then specify how much detail each stakeholder actually needs, using a simple three-level scale per view:
| Code | Meaning |
|---|---|
| d | Detail |
| s | Some information |
| o | Overview only |
Build the stakeholder × view matrix, fill it with d/s/o, and the view set — and the depth of each view — falls out of it. This is what stops you writing a Deployment view in loving detail for an audience that needed one paragraph.
Integration and interface documentation
Interfaces are documented as part of a view, in the element catalog. If the document is standalone, additional sections are required — for example system context.
Multiple resources are specified in a single document. However, having a separate document for each integration point is better from the development and change-management process perspective.
The SEI interface specification template
| Section | Content |
|---|---|
| 1. Interface identity | What this interface is, and its version |
| 2. Resources provided | The points of interaction — methods of an interface of a class, messaging endpoints, CRUD operations for a REST resource. An interface can be considered as a collection of resources. For each resource, document the three items below |
| → Resource syntax | Signatures of functions/services, arguments and data types |
| → Resource semantics | Visible behaviour — changes in externally visible state — and restrictions. Recommended to use preconditions, postconditions and some formal language |
| → Error handling | "Nominal flows are only the tip of the iceberg." Error conditions and exceptions: wrong arguments, wrong state, wrong environment |
| 3. Data type definitions | For the data passed and returned by the resources. Constants are more relevant for program interfaces |
| 4. Configuration parameters | And how they affect the semantics — a parameter that changes behaviour is part of the contract |
| 5. Rationale | The reasons and motivation behind the interface's design |
Data mapping is usually highlighted but generally should be documented in a separate document; if provided inline it cannot serve as the integration contract.
Architecture Decision Records
Views capture what the architecture is. ADRs capture why, one decision at a time, in a lightweight file that lives beside the code.
The technique comes from Michael Nygard's 2011 post Documenting Architecture Decisions, and the community has since standardised templates and tooling at adr.github.io. The value for a solution architect is direct: the Rationale sections of your views answer "why this design", but an ADR log answers "why this design rather than the alternative we rejected in March" — which is the question that actually arrives six months later, usually from someone new.
A minimal record is short by design: the context that forced a decision, the decision itself, its status (proposed / accepted / superseded), and the consequences — both the benefits and the costs you are accepting. A superseded ADR is never deleted; it is marked superseded and linked to the one that replaced it, so the reasoning chain survives.
This pairs naturally with the Timely and evolutionary documentation attribute above: you cannot write a big up-front design honestly, but you can record each decision as it is made.
Documenting a service-oriented solution
View-based documentation organises by structure. When the solution is a set of collaborating services, an alternative that often reads better is to organise by service, with an identical template repeated for each one. The repetition is the feature — it makes the document navigable, and a missing section becomes obvious.
A workable per-service template:
| Section | Content |
|---|---|
| Role in business processes | Which processes the service participates in, and what it contributes to each |
| Interfaces | Contracts provided and consumed, each documented per the interface template above |
| Externally observable structure | What a consumer can see — deliberately excluding internals |
| Externally observable state | The state consumers may depend on, and its lifecycle |
| Coordination and ordering | How it sequences with other services; what ordering guarantees it offers and requires |
| Constraints | What limits it — capacity, licensing, data residency, ownership |
| Quality attribute behaviour | Its share of the performance, availability, disaster-recovery and security budgets |
That last row is the one teams skip, and it is the one that makes the document useful. A service description without its share of the budget cannot be held to anything.
Deriving quality attribute requirements from business arithmetic
This is the single most valuable technique in the course, and the one most often skipped. The usual failure is asking the customer "how many nines do you need?", receiving a number chosen by intuition, and designing to it. The alternative is to compute it.
Worked on Lumen's settlement subsystem — the component that submits completed studies for payment.
Step 1 — establish the unit economics
| Fact | Value |
|---|---|
| Settlement submissions per day | 60,000 |
| Cost of an automated submission | $0.40 |
| Cost when a submission fails and requires manual rework | $12.00 |
| Penalty per failure | $11.60 |
| Margin per settled study | $3.10 |
| Peak arrival rate | 9,000 per hour |
Two consequences fall straight out:
- One manual rework erases the margin on ~3.7 successfully settled studies ($11.60 ÷ $3.10). That is the argument for a low failure rate, expressed in a currency the business already uses
- An hour of outage costs ~$104,400 (9,000 × $11.60), because submissions that cannot be processed automatically become manual rework
Step 2 — turn a cost appetite into an availability figure
Suppose the business will tolerate $250,000 per year in outage cost — a number a finance director can actually opine on, unlike "nines".
$$\text{tolerable outage} = \frac{$250{,}000}{$104{,}400/\text{hour}} \approx 2.4 \text{ hours per year}$$
$$\text{availability} = 1 - \frac{2.4}{8{,}760} \approx 99.97%$$
Cap a single incident at 15 minutes and 2.4 hours becomes a budget of roughly 10 incidents per year — which is now a statement operations can be measured against, and which tells you how much detection-and-recovery automation is worth building.
The direction of reasoning is what matters. Nobody asked for 99.97%; it was derived from volume, cost differential and arrival rate. This also answers "how much may I spend improving availability?" — any investment that removes outage hours and pays back against $104,400 per hour is justified, and one that does not, is not.
Step 3 — decompose the budget across components
A system-level number is unusable until each component knows its share. Four components sit in the settlement path, in series:
$$A_{\text{component}} = \sqrt[4]{0.9997} \approx 99.99%$$
| Scenario | Overall | Intake Gateway | Eligibility Service | Settlement Engine | Payment Adapter |
|---|---|---|---|---|---|
| Availability | 99.97%, max 15 min per incident | 99.99% | 99.99% | 99.99% | 99.99% |
| Standard submission latency | 6.0 s | 0.2 s | 1.5 s | 3.0 s | 1.3 s |
| Large monthly batch, per partner | 90 s | 0.4 s | 20 s | 55 s | 14.6 s |
The monthly reconciliation run covers ~600 partners at 8 s each, so the full batch must complete inside 2 hours — 80 minutes of work, leaving headroom for retries.
And then the tactic that makes those component figures achievable rather than aspirational:
To avoid placing an unreasonable availability demand on any single component, deploy at least two instances of each behind a health-checked balancer. Four components each needing 99.99% as a single instance would be an expensive and fragile promise; the same figure from a redundant pair is routine.
Note the corollary, which is where teams get caught: series composition multiplies. Adding a fifth component to this path drops the achievable total unless every component gets stricter. The cheapest availability decision available to an architect is usually removing a hop, not hardening one.
SAD templates worth starting from
Do not invent a document structure. Start from a published one and adapt it — then record why you adapted it.
| Template | Source | Character |
|---|---|---|
| Views and Beyond | SEI, Documenting Software Architectures | View-centric. Strongest when the architecture's difficulty is structural, and you need the view packet discipline described above |
| arc42 | arc42.org, freely licensed | Twelve fixed sections, deliberately lean. The most practical default for a team that will actually maintain the document — and it explicitly includes quality requirements, risks and technical debt, and design decisions |
| TOGAF Architecture Definition Document | The Open Group | Enterprise-oriented, aligned to the ADM phases. Strongest where the solution must demonstrably fit an existing enterprise architecture |
| Corporate outline | Most consultancies have one | Typically a Baseline → Target → Transition spine, which is the right shape for brownfield engagements. Worth reproducing even if you use a different template, because it forces the migration question |
The Baseline → Target → Transition spine
Whatever template you start from, a brownfield engagement needs these three in sequence, and the reason is not bureaucratic:
Baseline architecture — what exists today, at sufficient detail to migrate from
Target architecture — what you propose, with risks, dependencies, assumptions
Transition — how you get from one to the other without stopping the business
Baseline applies only to brownfield. In a greenfield engagement there is no baseline architecture and the section should be deleted rather than filled with apologies. Conversely, in a brownfield engagement the section teams most often omit is Transition — which is where the actual difficulty lives.
Mark every section with its obligation
The single most useful adaptation to any template is to annotate each section with whether it is Mandatory, Recommended, or Optional for this engagement, and delete what is neither. This is what makes a template adaptable rather than a checklist to fill blindly — and it converts "the document is incomplete" into a decision someone made on purpose.
A component record worth repeating
For each architecturally significant component, in both baseline and target:
| Field | Content |
|---|---|
| Purpose | What the component is for, in one or two sentences |
| Technology stack | Principal frameworks, libraries, runtimes and managed services |
| Related components | Each relation named, with the nature of the relation — calls, publishes to, reads from, is deployed with |
| Requirements covered | Which functional requirements and which quality attribute scenarios this component satisfies |
| Notes | Anything else a reader needs, including known debt |
That fourth field is the traceability hook, and its absence is the most common serious defect in architecture documents: a design that never states which requirement it satisfies cannot be reviewed, and quality attribute requirements silently go unaddressed.
Exercises — Module 6
- Review the provided scenario
- Create your own Software Architecture Document for the scenario, based on one of the public templates (arc42, SEI Views and Beyond, the TOGAF Architecture Definition Document, or a corporate outline)
- Adapt the structure — remove unnecessary and non-relevant chapters, e.g. "Baseline architecture" for a greenfield project
- Remove all redundant help descriptions from the template
- Add chapters that you think should be added
- For each chapter and section, describe its purpose and its potential content in a few sentences — what should be documented there. Filling the sections with details is optional
- Fill in the appropriate sections with the results of your previous homework: Business Architecture, ASRs and Quality Attributes
- Select any views school you like — C4, SEI, 4+1, Rozanski & Woods
- Document 3 or more architectural views and add reasonable textual description to them. It is not required to fill in all sections, but adding textual description to your views is very preferable
- Ensure the architectural decisions you made and the descriptions you provided while drawing the views are clearly mapped to the requirements
Module 7 — Pre-sales, Estimation, Discovery, Construction, Transition
Engagement models
The engagement model is not commercial trivia — it determines what you are allowed to assume about team stability, scope change and who carries the risk of being wrong. The spectrum, roughly in order of how much the supplier owns:
| Model | Description | Architectural consequence |
|---|---|---|
| Project-based / defined scope | The supplier delivers an agreed scope. Reduces cost and time to market by buying expertise and capacity you do not have | Weakens badly when requirements evolve, or when the relationship will outlast one project. Pushes toward up-front design because change is expensive to transact |
| Dedicated team (often an offshore or nearshore development centre) | The client drives requirements; the supplier manages staffing, retention and ramp-up. Accommodates variety — new development, legacy modernisation, maintenance, testing | Team continuity makes incremental architecture viable. You can defer decisions because the people who made them are still there |
| Managed product development | The supplier owns end-to-end delivery: product management, architecture, implementation, operations and support | The architect owns outcomes rather than documents. Operational qualities — observability, deployability — stop being someone else's problem |
| Platform partnership | The supplier operates a platform on a continuing basis rather than delivering a project | Design for continuous change is the whole job. Total cost of ownership dominates build cost in every decision |
Two practical notes. The pricing model is often implied by the engagement model — staff augmentation tends to time-and-materials, defined scope tends to fixed price — and each puts the risk of estimation error on a different party. And architects are rarely involved in contract negotiation, which is usually owned by sales, account and delivery management; but you should know which model you are working under, because it silently sets the design constraints above.
Estimation: art and science
| Character | |
|---|---|
| Science of estimation | Very mathematically intensive and can be quite accurate. Gives you theoretical numbers. Best implemented by software tools |
| Art of estimation | Involves heuristics and rules of thumb. Gives you practical help on real projects. Works best when supported by the estimation science |
The common idea is that an estimate is a prediction of the project outcome.
DeMarco additionally introduces a quality — or accuracy — attribute of the estimate. According to him the default definition among professionals is "the most optimistic prediction that has a non-zero probability of coming true". He argues a better definition is "a prediction that is equally likely to be above or below the actual result."
Over- vs underestimation
100% accurate estimates are very rare, so if we are going to err, is it better to err on the side of overestimation or underestimation? The penalties are asymmetric:
| Direction | Penalty | Why |
|---|---|---|
| Underestimation | Nonlinear and unbounded | Planning errors, shortchanging upstream activities, and the creation of more defects cause more damage than overestimation does |
| Overestimation | Linear and bounded | Parkinson's Law and Student Syndrome. Work will expand to fill available time, but it will not expand any further |
- Parkinson's Law — "work expands so as to fill the time available for its completion". If you give a project team 6 months to complete a project that could be completed in 4, the team will find a way to use up the extra 2 months
- Student Syndrome — if developers are given too much time they'll procrastinate until late in the project, at which point they'll rush to complete their work, and they probably won't finish on time
In practice, significant overestimation leads to an underestimation-like effect because of artificial increasing of scope. There is an error range which doesn't cause any significant problems: 5%–10%.
Accuracy vs precision
Precision is independent of accuracy. People make assumptions about accuracy based on precision, so the precision you use should match the accuracy of your estimates.
A good analogy: imagine a basketball player shooting baskets. If the player shoots with accuracy, their aim will always take the ball close to or into the basket. If the player shoots with precision, their aim will always take the ball to the same location, which may or may not be close to the basket. A good player will be both accurate and precise — shooting the ball the same way each time and each time making it in the basket.
Inputs, outputs, and the sources of uncertainty
Input information consists of information about the project being estimated and about the capabilities of the organization that will be implementing and delivering it.
- Project data includes requirements both functional and non-functional, priorities (e.g. quicker is better) and constraints (e.g. the technology stack is already defined)
- Organizational influences include data about the organization's processes and the personnel's experience and skills
Output consists of estimated scope, effort, schedule and cost.
The estimation procedure itself has to be unbiased and should produce the same output on the same input data. The project data can be adjusted until the estimation process produces an acceptable outcome.
There are two main sources of estimation uncertainty: incomplete or inaccurate input data, and inaccuracies of the estimation process itself.
| Cause | Effect |
|---|---|
| Omitted functional and especially non-functional requirements | Errors in project size estimation |
| Wrong assumptions about personnel's skills and performance | Errors in both effort and schedule estimation |
| Forgotten activities such as requirement analysis | Errors in effort estimation |
| Insufficient experience in the particular business area | Errors in project size estimation |
| Unfamiliar technologies | Wrong assumptions about performance, and thus errors in effort estimation |
The cone of uncertainty
Software development is a process of gradual refinement. You start with a general product concept — the vision of the software you intend to build — and refine that concept based on the product and project goals. Uncertainty in a software estimate results from uncertainty in how the decisions will be resolved; as you make a greater percentage of those decisions, you reduce the estimation uncertainty.
- The cone represents the best-case accuracy that is possible to have in software estimates at different points in a project
- The cone doesn't narrow itself. It narrows through project control. If the project is not well controlled, the cone of uncertainty becomes a cloud of uncertainty
- The schedule variability is much lower than the effort variability, because schedule is calculated as a cube-root function of effort for large projects
Expressing probability
The curve of a probability distribution describes the probability associated with different estimate values; each point represents the chance of the project finishing exactly on that date, or costing exactly that much. What you usually want is the probability of delivering on or before a particular date, or at or below a specific cost or effort.
You can express probabilities in numerous ways:
- A "percent confident" attached to a single-point number — "we're 90% confident in the 24-week schedule"
- Best case and worst case, which implies a probability — "we estimate a best case of 18 weeks and a worst case of 24 weeks"
- A range rather than a single-point number — "we're estimating 18 to 24 weeks"
- A plus-or-minus qualifier — "6 months, ±1 month"
- A confidence factor — "there is 80% probability we can deliver by the end of Q4"
The key point is that all estimates include a probability, whether the probability is stated or implied. An explicitly stated probability is one sign of a good estimate.
An essential practice in presenting an estimate is to document the assumptions embodied in it. Then, if the project unfolds in a way that invalidates the assumptions, you can point back to the estimate assumptions as a basis for revising the estimate. The way you communicate an estimate suggests how accurate it is — if your presentation style implies an unfounded accuracy, you lay the groundwork for a difficult discussion about the estimate itself.
Work Breakdown Structure
There are broadly two approaches to WBS breakdown, plus mixed:
| Type | Definition |
|---|---|
| Deliverable-oriented (product WBS) | A hierarchical structure of things that the project will make, or outcomes that it will deliver. It's a classification of the project scope |
| Task-oriented | A hierarchical structure of tasks that, when completed, will result in satisfaction of all project commitments. It's an exhaustive list of work |
Questions the course poses for discussion:
- What are the benefits of the deliverable-oriented WBS? Of the task-oriented WBS?
- What WBS is potentially more accurate?
- What WBS leads to easier change of the overall estimate and schedule?
A concrete case to reason about: you need to estimate Reporting, where you will need to build a core reporting framework plus a set of concrete reports. Deliverable. Task. Deliverable.
Estimation techniques
Decomposition is the practice of separating an estimate into multiple pieces, estimating each piece individually, then recombining the individual estimates into an aggregate. Also known as "bottom up" estimation.
Decomposition takes advantage of The Law of Large Numbers: if you create one big estimate, the estimate's error tendency will be completely on the high side or completely on the low side. But if you create several smaller estimates, some errors will be on the high side and some on the low side — the errors will tend to cancel each other out to some degree.
The four main steps of the estimation process: preparation → estimation of the development efforts → estimation of other activities → finalization.
It is important to estimate non-development activities. Examples: DevOps, business analysis, quality assurance, documentation. You can involve QA, BA and other specialists to help estimate them, or estimate them as a percentage of development efforts.
Conclude by creating the baseline schedule based on your estimated total. You can optionally check your total by using another estimation method.
Always agree what exactly you include in the "Development" activity — the idea is always to be on the same page, because development can include or not include unit testing, integration testing, dev documentation, architectural design, deploy, and so on.
Wideband Delphi
- The Delphi coordinator presents each estimator with the specification and an estimation form
- Estimators prepare initial estimates individually. Optionally this step can be performed after step 3
- The coordinator calls a group meeting in which the estimators discuss estimation issues related to the project at hand. If the group agrees on a single estimate without much discussion, the coordinator assigns someone to play devil's advocate
- Estimators give their individual estimates to the coordinator anonymously
- The coordinator prepares a summary of the estimates on an iteration form and presents it to the estimators so they can see how their estimates compare with others'
- The coordinator has estimators meet to discuss variations in their estimates
- Estimators vote anonymously on whether they want to accept the average estimate. If any of the estimators votes "no", they return to step 3
- The final estimate is the single-point estimate stemming from the Delphi exercise. Or, the final estimate is the range created through the Delphi discussion, and the single-point Delphi estimate is the expected case
Estimation by analogy
The idea is simple: you create estimates for a new project by comparing the new project to a similar past project.
- Normally works well in accounts working in a concrete domain and/or with limited technologies and platforms — e-commerce, insurance
- It is important to use the actual results of the old project and not the old project estimates
- Can give quick results if you can find a similar project to compare to
- But the accuracy quickly decreases as the number and magnitude of differences between the projects grows
Story points and #NoEstimates
Approaches to story points: known velocity; defining a transformation coefficient — bad practice; trying to guess velocity; using ideal hours and a load factor.
The #NoEstimates movement explores alternatives for estimation.
Two rules hidden in the estimation jokes
- All estimation techniques are based on previous experience. Model-based techniques use industry-average data; proxy-based (learn-oriented) techniques use the organization's historical data; expertise-based techniques use personal previous experience
- Project scope has to be defined as clearly as possible
A practice exercise the course uses: estimating something concrete where students must ask clarifying questions and provide several approaches. The core idea — simply count and calculate; use judgments (e.g. "I think the hall is 70% full") only as a last resort.
Schedule compression
If there is a business need to compress your schedule, keep in mind that shorter schedules require more effort for several reasons:
- Larger teams require more coordination and management overhead
- Larger teams introduce more communication paths, which introduce more chances to miscommunicate, which introduce more errors, which then have to be corrected
- Shorter schedules require more work to be done in parallel. The more work that overlaps, the higher the chance both that one piece of work will be based on another incomplete or defective piece, and that later changes will increase the amount of rework
There is also a limit to how much you can compress your baseline schedule.
Discovery
A high-level picture of possible participants exists, but the list can vary depending on actual needs. There are major roles plus a few more, and normally a coordinator is an Account Manager. The list of responsibilities is not exhaustive and depends on the account or project.
- The discovery approach should be defined and communicated to the client. A sample: 6 weeks, two streams involved, on-site/offsite presence varies
- In order to get valuable deliverables, the team should define and communicate to the client the assumptions (e.g. schedule, availability of key stakeholders) and the technical prerequisites
- A sample-template of an on-site agenda is provided
- Important: define and confirm with the client a set of expected outcomes, for example:
- A report including key issues and recommendations, if this is brownfield
- A roadmap
- Solution design and estimate
QAW, or any of its lightweight versions, can be used at this stage — details in Module 3.1.
Construction
The idea of the Construction module is to cover the different areas solution architects can be responsible for or involved in during a project implementation phase. Clients and projects are different, therefore SA activities at this stage vary.
To the common question of what an architect should do during implementation, the generic but real answer: we work for and together with our customers, so we as architects must do everything from our side to ensure that projects are completed on time and with the required quality.
In a typical agile project the architect is involved in:
- Initial design during the inception phase — the Initial Architecture Vision
- Estimations
- Up-front design for the next iterations/releases
- System redesign
- Design of new or complex functionality
Note: at SA L1 level, treat architecture governance mostly as implementation governance — following the best practices, doing architecture and code review, writing useful documentation. Architecture governance as part of an EA framework is a somewhat different thing and out of scope.
A useful model here is Lencioni's three virtues of an ideal team player, which map unusually well onto architecture work:
| Quality | A team player who is… |
|---|---|
| Hungry | Self-motivated and hard-working; always thinks about the next step and next opportunity to contribute; always looking for more to do, more to learn and more responsibility; never wants to be considered a person who avoids work or effort |
| Humble | Lacks excessive ego and is not concerned with their status; quick to point out contributions of others and slow to seek attention for themselves; puts the team over self; defines success collectively rather than individually |
| People Smart | Has common sense about people; actively listens to others and stays engaged in conversations; asks good questions; has good judgement and intuition about the subtleties of group dynamics; understands the impact of their words and actions |
There are different approaches to the test pyramid; the one presented is just one of them.
Hardware selection
Primary resources are the typical resources that matter for most types of solutions. Additional resources are important for special scenarios:
- GPU grids are often used for video encoding and for deep learning (neural networks). There are cases where neural network training performance on 1 GPU node (AWS P2) was the same as on a cluster with 144 CPUs — by replacing CPU nodes with GPU nodes the solution became 20× more cost effective
- Disk size is important for large DBs, NoSQL and big data solutions
- Physical size/dimensions and energy consumption are critical in IoT and wearable devices
Normally, software performance is bound to one or more primary hardware resources. Knowing which types of workloads and solutions are CPU-bound or memory-bound helps make initial estimations or pick starting points for performance testing.
CPU
| Concept | Detail |
|---|---|
| CPU bound | Improving the CPU — faster, more cores, better cache — will improve application performance; the application spends the majority of its time using the CPU doing calculations |
| I/O waits | The application is not using CPU and is waiting for I/O — reading from disk, making a request over the network to a DB or service |
| Cores vs threads | If your application doesn't have any I/O waits, which is rare, optimal performance is when the number of threads equals the number of cores |
| Context switching | Having more running threads than cores leads to interrupting one task and switching to another, which adds CPU overhead. With no I/O wait, context switching degrades performance. When there is I/O wait it is totally acceptable and common practice to have more threads than cores |
| Metrics | CPU usage and load average are the typical metrics. CPU utilization should normally be below 70–80%, and load average — tasks for CPU waiting in queue — below 0.7 per core |
Memory
Memory on the node is consumed not only by your application — there are other consumers such as the kernel, page cache, daemons and agents. It's not uncommon to leave extra free memory unallocated to leave more space for page cache, especially in disk-I/O-heavy applications like databases and NoSQL data stores.
- Adding more memory is not the right way to solve memory leaks — address it in your application instead
- Swap can extend memory with disk space but slows performance when used; therefore in cases where high performance is required, swap should be turned off
- The Linux kernel OOM Killer will kill your process if it considers it too aggressive in memory consumption. Ensure proper hardware and app allocated memory sizing, and keep memory utilization below 70–80%
- Garbage collection performance — allocating too much memory to a process using a GC-backed runtime (JVM, CLR, JavaScript, Go) can and normally will impact performance. Ideally keep nodes smaller and spread memory across the cluster. Depending on the runtime you may want to keep RAM allocated below 8–16 GB, otherwise investment in GC tuning may be required
Disk
| Metric | Definition | Most critical for |
|---|---|---|
| IOPS | Input/output operations per second — the number of IO operations a disk can perform per second, disregarding the size of each operation | Operational storages based on RDBMS or NoSQL |
| Throughput | IOPS × IO size — the volume of IO operations handled per unit of time (GB/s) | Big data and analytical solutions |
| Latency | How fast a single IO operation can be performed (ns, ms) | Low latency systems |
Different storage is optimized for different types of performance, so the choice depends on the quality attributes of the system.
- SSD vs HDD — SSD often provides better performance, especially latency on random reads/writes. The difference on sequential access patterns is less significant. The primary drawback of SSD is cost
- Local attached disks vs network storage (SAN, NAS) — network storage provides a lot of benefits especially from a maintenance and reliability perspective, and in most cases better TCO. At the same time, using network storage removes "data locality", which is critical for data-intensive applications, increasing disk operation latencies and network I/O
- Access patterns — random vs sequential, read-intensive vs write-intensive vs mixed. Disks have different effectiveness with different access patterns (see the HDD vs SSD example), so understand your solution's access patterns to make a proper disk selection
- Security — data security at rest is critical for most solutions. While software encryption is often sufficient, some solutions require advanced security either forced by regulations like FIPS or by protecting sensitive information. In those cases, disks with hardware-based security may need to be considered — with support of SED and ISE
Network
Network is a huge topic deserving its own deck; these are the key points covering the needs of most solutions.
| Metric | Definition | Critical for |
|---|---|---|
| Bandwidth | The max rate of data transferred (MB/s) | — |
| Throughput | The actual data transfer rate | Large-volume data transfer solutions: big data, video streaming, some ML scenarios like neural networks on distributed GPU grids |
| Latency | The delay between sender and receiver first byte | Low latency solutions |
Reliability — jitter, error rate, network partition — has significant impact on certain types of solutions:
- Networks with high jitter are not suitable for low-latency solutions: despite "advertised" network performance that might provide sufficient latency in theory, high jitter will cause it to regularly breach SLAs
- Network partition rate is critical for data stores that are on the CP side of CAP but at the same time try to maintain high availability. Google Cloud Spanner is a CP data storage that maintains 99.999% due to the high quality of Google's network, where network partitions are extremely rare
Software-defined networking (SDN) built on top of network hardware topology can have huge impact on performance and reliability. For example, Google's Andromeda SDN upgrade from version 2.0 to 2.1 reduced network latency for intra-zone VM communication by 40% while using the same hardware.
Security — network security is critical for most modern solutions, and this is one of the biggest challenges in the IoT field. While for most solutions generic cloud network hardware security plus correct network topology (DMZ, VPCs) plus software security (encryption) is enough, additional hardware options exist such as Hardware Security Modules (HSM).
Sizing for availability and geography
Multi-region requirements are driven not only by availability and DR SLA but by the geographical distribution of consumers. At the same time the number of availability zones is purely availability related.
Going below the minimal number of nodes will breach the availability SLA — therefore if that number of nodes provides more capacity than your application needs, consider downsizing the nodes rather than reducing their count.
Autoscaling delay
There is a delay. You normally don't want to increase the number of instances in a cluster the moment utilization reaches a threshold (e.g. CPU > 80%), as it could be an occasional spike. The common approach is to set autoscaling to kick in after the threshold was passed for a few sequential minutes. Bear in mind that once new nodes are added, there is extra start-up time for your app, ranging from milliseconds to minutes depending on its type.
$$\text{autoscaling delay} = \text{autoscaling time threshold} + \text{app startup time}$$
In some cases stress arresting is required to ensure your app can survive big spikes until autoscaling kicks in. With that said, delay in autoscaling is not always suitable for low-latency applications, as typical stress-arresting techniques break latency SLAs — those scenarios require preemptive scaling.
For distributed datastores that leverage sharding or partitioning, autoscaling is rarely used, because changing the topology of a partitioned cluster often requires re-partitioning before a node can start serving requests. On large volumes of data this may take hours, and the load spike can be over by then. At the same time, for non-partitioned data stores, creating additional read replicas is a much faster process and can be considered for autoscaling.
Sizing tactics
Estimation tactics are usually employed in the initial stages of the project, when it is not possible to test whether a hardware configuration will correspond to the solution's quality attributes. Often used as a starting point for the first performance testing.
| Tactic | Example |
|---|---|
| Similar systems | "We had a previous version of our service running on 15 c4.large nodes; as we didn't make any significant changes that might affect performance, we will start with the same cluster" |
| Previous experience | Examples of CPU/RAM/disk/network-bound systems that give you an idea of what type of resource would be most needed for your solution |
| Calculation based | Knowing the number of rows in your DB and their size, you can estimate the total data volume. Knowing the size of request/response and max connections to your service, you can estimate the RAM required |
| Vendor recommendations | Unless it's a fully custom-built app, most software products (DBs, NoSQL) have recommended hardware requirements. Remember it is not possible to provide recommendations for every possible use case — never trust them as-is |
| Zooming / proportional testing | If developing a bank system, measure performance on 1K transactions per 100 users, then propagate the results to the ASRs accordingly |
Fact-based tactics are based on monitoring of a real implementation as close as possible to production, often peak, loads.
| Tactic | Example |
|---|---|
| Current system | Whether it is a modernization effort or a cloud migration, whenever there is an existing system, collect as many metrics as possible. Not only may some hardware requirements stay the same, it will also help with estimations |
| Performance testing | Critical for hardware sizing — make sure you test for peak loads as well |
| Shadow traffic | If replacing an existing implementation, before releasing to production it is not uncommon to route production traffic to it so traffic goes to both old and new solutions, while the old one still serves production responses. Not a replacement for performance testing, as it might not show behaviour under peak load — but the benefit is that it is real traffic, as opposed to the often synthetic tests used in performance testing |
| Production monitoring | Once the system is in production, monitor it closely to see if you under- or over-provisioned hardware resources, and adjust accordingly |
| Cloud clone | Use cloud infrastructure to test a full clone of the system — rent cloud capacity for a short period on a separate account, monitor performance and VM loads, then estimate the resources actually used |
| "The best one minus one" | A top-level CIO tactic: when customers go for hardware they are OK to pay for good enough, but not top-notch systems. So select the line-up above the average — not Intel Core i9, but i7 |
Which tactics you apply depends on what information you have or can get. If you have an existing system and are replacing it, you can use the same RPS adjusted with usage growth projections and other factors. If this is a completely new system you'll need to get creative and estimate the number of concurrent users and their behaviour. If it is a service consumed by other existing services, you can look at their RPS.
Most distributed data platforms publish minimum and recommended production cluster specifications — node class, memory, disk type and node count. Use them as the starting point for performance testing and adjust from measurement, never as the answer.
Worked performance-testing iteration
A simple microservice that just serves GET requests. Expected peak load 3,000 requests per second; SLA: response latency percentile 95 shouldn't exceed 20 milliseconds.
| Step | Approach | Outcome |
|---|---|---|
| 1. Start small | Start with a small hardware sizing you believe makes sense based on experience or an estimation-based technique. Start with small loads too and increase gradually to see where the system breaks or slows down | In both cases the target 3k RPS was not reached, CPU utilization was high, and the latency SLA was breached |
| 2. Interpolate | From the observations CPU was obviously the bottleneck, so increase both the number of CPUs per node and the number of nodes. Also, while memory wasn't bottlenecked it constantly held at 80% utilization, close to max, so add memory as well | This setup reached the required 3k RPS without issues. But CPU utilization at peak was 22% — it looks like we over-provisioned |
| 3. Optimize | Reduce the size of the cluster, since we over-provisioned | Under-provisioned this time, but not as badly as on the first run. Pretty close |
| 4. Final result | Increase cluster size one more time | Found the happy medium: CPU utilization at 53% under peak load, which is safe even if the workload is slightly higher than expected peaks |
Usually performance testing takes much more iterative steps than in this example, especially where your service is backed by a data storage where you have impact on hardware sizing as well — in that case you have much more variability of parameters to test.
APM and TCO
APM (Application Performance Monitoring) has a typical flow of analysis through the solution.
TCO — as solution architects we must understand what TCO means and why the business cares. It is life-cycle cost analysis, not merely build cost, and the dominant term is maintenance.
How much of a system's lifetime cost is maintenance? Software engineering literature has put it at roughly 60–80% of total lifetime cost for decades, and studies vary mainly in how they draw the boundary. The corollary for an architect is uncomfortable: most of the money is spent after you have gone, and a large share of it is spent working around decisions made early.
The classic decomposition comes from Lientz and Swanson — corrective, adaptive and perfective maintenance — with preventive added later by ISO/IEC 14764. Typical shares, which vary by study but not in their ordering:
| Maintenance type | What it is | Rough share |
|---|---|---|
| Corrective | Fixing defects found after deployment | ~20% |
| Adaptive | Changing the system so it stays effective as its environment changes | ~25% |
| Perfective | Improving performance or maintainability without changing behaviour | ~5% |
| Enhancement | New capability — continuing functional evolution | ~50% or more |
Read that table next to the Module 3 modifiability material and the conclusion is uncomfortable but useful: the majority of what you will spend on a system after release is not fixing it — it is changing it. Which is precisely why binding time, cohesion and coupling decisions dominate TCO, and why "we'll make it flexible later" is the expensive option.
Worked estimate — Lumen Diagnostics
The Module 7 exercise applied to the case study. The value is in the stated rules and the traceability, not the numbers.
Ground rules that separate an estimate from a guess
- State what is included — core development, unit tests, integration tests, documentation — and what is not — business analysis, support, training
- Separate by category — front end, back end, data, operations. This separation is what makes a resource plan possible at all
- Decide deliberately whether architecture effort sits inside development or is estimated as its own line
- Discovery and transition belong in the plan. If your estimate excludes them, say so explicitly rather than letting the omission pass silently
- Non-development work — management, business analysis, QA — is commonly estimated as a percentage of development effort, which is defensible only if you state the percentage and why
- Every number must reconcile with the resource plan. If development totals 100 person-days, roughly 100 days of development roles must appear in the plan. A total that does not reconcile is a total nobody checked
- For the discovery phase, produce an activity grid — days across, sessions down, each cell naming the activity and who must attend
The percentage rules, and why they are a judgement
| Rule | Typical range | What moves it |
|---|---|---|
| QA effort as a share of development | 20–60% | A system with a hard performance SLA needs a performance specialist as well as functional testing, which is what pushes it toward the upper end. A straightforward CRUD portal sits near the lower end |
| Management as a share of total team effort | ~10% | Team count and number of parties to coordinate |
| Operations engineering | Spans the whole delivery | Not a phase. Environments, pipelines and observability are needed from the first sprint to the last |
Pick a figure, write down the reasoning, and defend it in review. A ratio quoted without reasoning is the most common way an estimate becomes indefensible under pressure.
Shape of the work breakdown
Deliverable-oriented, with days per role (SA · BA · Front end · Back end · Data · Ops · QA):
| Phase | Deliverable | Representative activities |
|---|---|---|
| Discovery | Onboarding | Review the referral-management and identity integrations; assess partner-practice capability and data quality |
| Workshops | Stakeholder interviews, a quality attribute workshop, requirement and constraint refinement and sign-off | |
| Finalisation | Produce the architecture document: application, data and integration architecture | |
| Implementation | Foundations | Provision environments; establish the delivery pipeline; define and document access roles; set up the documentation space |
| Architecture and design | Application architecture, data architecture, integration architecture, per-region deployment topology | |
| Platform capabilities | Workflow configuration service; offer-and-confirmation service; availability search; notification service; logging, audit and monitoring | |
| Portals | Patient portal; administration portal; partner portal; each with its own API surface | |
| Integrations | Referral-system synchronisation; identity service; single sign-on; the one automated partner API; manual upload path | |
| Testing | Functional, integration, performance and residency-compliance testing | |
| Transition | Readiness | Production configuration, data migration and reconciliation, runbooks, support handover |
| Launch | Phased regional rollout with rollback plan |
Roll the days up per role, apply a rate per role, and the resource plan produces the cost. That final step is only possible because the estimate was separated by category in the first place — which is why that ground rule is not bookkeeping.
Worked cloud cost model
The Module 9 exercise asks you to calculate running cost. The method matters more than the arithmetic: derive call volumes from user behaviour, then apply the price list. Never the reverse — a spreadsheet that starts from prices tells you nothing about what to change.
Step 1 — the load drivers
| Driver | Value | Assumption |
|---|---|---|
| Named users (staff, partners, patients with accounts) | 52,000 | 8% concurrent → ~4,160 concurrent sessions |
| Appointment and study records | 6.5 million | 12% updated monthly, 4% added → 1.04M record changes per month |
| Search index size | ~40 GB | Drives node sizing, not call volume |
Step 2 — derive per-service call volumes, showing the arithmetic
| Service | Monthly calls | Derivation |
|---|---|---|
| Scheduling orchestrator | 36,400,000 | 1.04M changes × 5 calls per stage × 7 workflow stages |
| Workflow configurator | 7,280,000 | 1 call per stage per changed record → 1.04M × 7 |
| Partner availability sync | 18,200,000 | Estimated at half the orchestrator volume |
| Availability search | 15,200,000 | 25% of concurrent users search 4×/hour → 4,160 searches/hour × 5 calls × 730 hours |
| Notification service | 4,160,000 | 1.04M changes × 4 calls per notification |
| Reporting | 2,000,000 | 8% of users run reports monthly, 40 reports each, 12 calls per report |
| Identity and user management | 250,000 | Low volume, dominated by session establishment |
| Patient feedback | 150,000 | Small share of appointments, plus browsing |
| Monitoring | 5,260,000 | 12 services × 60 checks/hour × 10 calls × 730 hours |
| Logging and audit | 5,260,000 | Comparable to monitoring |
| Data access layer | 41,820,000 | 50% of business-service call volume |
| Total | ≈ 136,000,000 |
Step 3 — apply the price list
Illustrative published list prices; substitute your provider's current rates.
| Item | Basis | Units | Monthly |
|---|---|---|---|
| API gateway | $3.50 per 1M calls | 136.0M | $476.00 |
| Functions — invocations | $0.20 per 1M | 136.0M | $27.20 |
| Functions — duration | $0.00001667 per GB-second | 17.0M GB-s | $283.39 |
| Notifications — email (80%) | $2.00 per 100,000 | 3.33M | $66.56 |
| Notifications — SMS (15%) | $6.00 per 1,000 | 624,000 | $3,744.00 |
| Notifications — push (5%) | $0.60 per 1M | 208,000 | $0.12 |
| Search cluster | $0.22 per node-hour | 2 nodes × 730 h | $321.20 |
| Search storage | $0.11 per GB-month | 40 GB | $4.40 |
| Total | ≈ $4,923 / month (~$59,000 / year) |
Three things to take from this, all of them architectural rather than financial:
The SMS channel is 15% of notifications and 76% of the entire bill. Unit economics beat volume intuition. That single line justifies a design conversation — make SMS opt-in, or reserve it for the stages where a missed message costs an appointment — and no amount of tuning elsewhere recovers comparable money.
The search cluster was sized from the index, not from traffic. 40 GB of index chose the node class; the call volume merely confirmed two nodes suffice. That is the "calculation based" sizing tactic applied literally.
The data access layer is 31% of all calls and is pure overhead. It appears in no requirement. It exists because the design put a layer there — which makes it exactly the kind of hop the availability arithmetic in Module 6 says to question.
Exercises — Module 7
- Review the provided scenario
- Create a WBS for this scenario — either delivery- or task-based, or mixed. If it is mixed, be attentive, because it can be tricky
- Estimate the effort
- Define a resource plan including all main roles
- Plan the Discovery Phase for the project:
- Provide a timeline
- Think about a list of activities and the project roles involved in these activities
- Define and show who will do what
- Define and write down expected outcomes
- Plan at least one week of the discovery in detail
Module 8 — Architecture Design, Review and Governance
Coverage note. The three decks in this module (8.1 Architecture Design, 8.2 Architecture Review, 8.3 Architecture Governance) are almost entirely image-based — 120 slides yielded roughly 1,300 words of speaker notes between them. What follows is everything the notes establish, organised around the authoritative frameworks they reference. For the full detail go back to the original slides, and to Software Architecture in Practice (3rd ed.), p. 72, chapter "Guiding Quality Design Decisions", plus the SEI ATAM material and TOGAF governance chapters.
This module covers three things in sequence: the general shape of an architecture design process, then Attribute-Driven Design as a concrete method, then evaluation and governance.
Design fundamentals
Recall that one can view an architecture as the result of applying a collection of design decisions. What the seven categories from Module 3 present is a systematic categorization of these decisions, so that an architect can focus attention on those design dimensions likely to be most troublesome.
- These categories are not the only way to classify architectural design decisions, but they provide a rational division of concerns
- The categories might overlap, and it's all right if a particular decision exists in two different categories — because the concern of the architect is to ensure that every important decision is considered
There are key universal points applied while designing a solution, and they are elaborated in the SEI chapter on guiding quality design decisions.
Architecture principles should be traced directly to the business drivers. This is a source of constraints and limitations.
Do not document ALL requirements.
Note on baseline: where the course speaks of baseline architecture it means brownfield projects with legacy systems — it's clear there is no baseline architecture in greenfield projects.
The big picture from SEI, with three main points:
- Different levels of architecture: Enterprise, System, Software
- Architecture comprises multiple structures: modules, component-and-connector, and allocation
- Input for the design process is Quality Attributes, Scenarios, Functional Requirements, Patterns and Tactics
The 'Solution Delivery' activities are not considered in detail here, because they were covered in the Estimation module.
Attribute-Driven Design (ADD)
Rendering diagram…
The structure of the method:
- Steps 1–7 constitute a design round
- Steps 2–7 constitute an iteration within that round; there can be several iterations in a round
- Each iteration focuses on achieving a particular goal
- The design we get after a particular round will be the input for the following rounds
A design round is generally performed in a series of design iterations, where each iteration focuses on achieving a particular goal. Such a goal typically involves designing to satisfy a subset of the drivers. For example, an iteration goal could be to create structures from elements that will support a particular performance scenario, or that will enable a use case to be achieved. For this reason, you need to establish a goal before you start a particular design iteration.
Refinement (step 3)
Satisfying drivers requires you to produce one or more architectural structures. These structures are composed of interrelated elements, and those elements are generally obtained by refining other elements that you previously identified in an earlier iteration.
Refinement can mean:
- Decomposition into finer-grained elements — a top-down approach
- Combination of elements into coarser-grained elements — a bottom-up approach
- Improvement of previously identified elements
For greenfield development you can start by establishing the system context and then selecting the only available element — the system itself — for refinement by decomposition. For existing systems, or for later design iterations in greenfield systems, you normally choose to refine elements that were identified in prior iterations.
Choosing design concepts (step 4)
Choosing the design concepts is probably the most difficult decision you will face in the design process, because it requires you to identify alternatives among design concepts that can be used to achieve your iteration goal, and to make a selection from these alternatives.
Instantiating elements (step 5)
Once you have selected one or more design concepts you must make another design decision, which involves instantiating elements out of the design concepts you selected.
For example, if you selected the Layers pattern as a design concept, you must decide how many layers will be used, since the pattern itself does not prescribe a specific number. In this example, the layers are the elements that are instantiated.
Sketching views (step 6)
The views you have created are almost certainly incomplete, so these diagrams may need to be revisited and refined in a subsequent iteration. This is typically done to accommodate elements resulting from other design decisions that you will make to support additional drivers.
This factor explains why we speak of "sketching" the views in ADD — creating a preliminary type of documentation. The more formal, more fully fleshed-out documentation of these views, should you choose to produce them, occurs only after a number of design iterations have been finished.
Architecture review and ATAM
Architecture review — a process where architectural decisions are evaluated as to how they enable or restrict the system in meeting its Architecturally Significant Requirements.
The module presents ATAM — the Architecture Tradeoff Analysis Method — through two lenses:
- A context view of the ATAM: what the inputs are, and what the outcome is
- A conceptual flow of the ATAM
Executive summaries
The module spends dedicated time on this, and the point is explicit: writing the right executive summary is critical — and difficult.
From the graduate-work guidance, after reading your executive summary the customer should see that:
- You understand the business, the current state and the goal(s)
- The proposed solution will cover the current and future needs
- The solution will be delivered on time and on budget
Architecture governance
The conceptual setup, worth reading slowly:
Suppose you are interested that an entity works in a way you want it to work. If you are managing the entity then you have the necessary authority to ensure it. However, if you don't manage the entity directly, then what do you do? To do anything you need to have some authority or influence over the entity. You can discuss with the management team of the entity and come to an agreement on what needs to be done. Then you also come to an agreement on how to ensure that what you have agreed is followed. In other words, you lay down a governance framework.
Useful analogies to reach for: how corporate governance works, and how a government makes all parties — physical and legal entities — follow rules.
The six characteristics
Adapted from Corporate Governance (Naidoo, 2002), and positioned to highlight both the value and the necessity for governance as an approach adopted within organizations and their dealings with all involved parties:
| Characteristic | Meaning |
|---|---|
| Discipline | All involved parties will have a commitment to adhere to procedures, processes and authority structures established by the organization |
| Transparency | All actions implemented and their decision support will be available for inspection by authorized organization and provider parties |
| Independence | All processes, decision-making and mechanisms used will be established so as to minimize or avoid potential conflicts of interest |
| Accountability | Identifiable groups within the organization — e.g. governance boards who take actions or make decisions — are authorized and accountable for their actions |
| Responsibility | Each contracted party is required to act responsibly to the organization and its stakeholders |
| Fairness | All decisions taken, processes used, and their implementation will not be allowed to create unfair advantage to any one particular party |
The three strategy elements
There are three important elements of an architecture governance strategy that relate particularly to the acceptance and success of architecture within the enterprise:
- Architecture Board
- Architecture Principles
- Architecture Compliance
The Architecture Board is presented as the first success factor of an architecture governance strategy.
It is important to consider all of these to ensure a successful approach to architecture governance, and to the effective management of the Architecture Contract.
Governance in practice
Concrete examples of architecture governance:
- Consistency between sub-architectures
- Identifying re-usable components
- Architecture compliance over the enterprise
The scenario to recognise: there are different units in an organization with different projects in these units. They can build overlapping frameworks and systems in their own way. The goal of an enterprise architect is to detect such a situation and mitigate or fix it — by identifying reusable components, creating consistency between sub-architectures, and so on. This is very important, but it is a bit outside the focus of a solution architect.
Architecture governance includes control, compliance, management, accountability — the core definition from TOGAF. It is one of the main activities of enterprise architects: any company wishing to be successful and build a business that will last decades should have an enterprise architect who, among other activities, engages in architecture governance.
Exercises — Module 8
No separate assignment. Design, review and governance are exercised through the graduate work, where your executive summary, ASR traceability and component-level detail are precisely what gets assessed.
Module 9 — Technology Domains
9.1.1 Virtualization, containers, orchestration
The usual teaching sequence for this domain, and a reasonable order to learn it in:
- Virtualization — concepts and types
- Containers — VMs vs containers, Docker
- Orchestration — scheduling, service discovery, rolling updates; in practice Kubernetes
- Non-functional capabilities of the resulting platform
9.1.2 Cloud core
The NIST definition
The NIST definition of cloud computing has been the most accepted and is used as the basic definition. A simplified version: remote computing resources provided as a service. By computing resources we usually mean network, computing units (virtual machines), and storage.
The NIST definition introduces five fundamental properties that characterize a cloud offering:
| Property | Meaning |
|---|---|
| On-demand self-service | A consumer can unilaterally provision computing capabilities |
| Broad network access | Capabilities are available over the network and accessed through standard mechanisms that promote use by heterogeneous thin or thick client platforms |
| Resource pooling | The provider's computing resources are pooled to serve multiple consumers using a multi-tenant model, with different physical and virtual resources dynamically assigned and reassigned according to consumer demand |
| Rapid elasticity | Capabilities can be elastically provisioned and released, in some cases automatically |
| Measured service | Resource usage can be monitored, controlled and reported, providing transparency for both the provider and the consumer |
Automated elasticity matters because the actual demand is often not what we can predict — automated elasticity provided by cloud can be far more beneficial than managing scale manually.
Cloud types: public, private, hybrid — and also a community cloud.
OpenStack is an open-source cloud operating system and community founded by Rackspace and NASA in 2010. It is an abstraction over the hypervisor and provides a unified interface to access the various resources — compute, storage (object and block), and network.
Service models
Security and compliance is normally a shared responsibility between the cloud provider and its customers — for example, the AWS Shared Responsibility Model describes such segregation.
| Model | Definition |
|---|---|
| IaaS | Gartner: a standardized, highly automated offering where compute resources, complemented by storage and networking capabilities, are owned by a service provider and offered to the customer on demand. The resources are scalable and elastic in near real time and metered by use. Self-service interfaces are exposed directly to the customer, including a web-based UI and an API. The resources may be single-tenant or multitenant, and hosted by the service provider or on-premises in the customer's data center — the public/private cloud distinction |
| PaaS | Platform services. In recent years Gartner combines IaaS and PaaS providers into one quadrant |
| hpaPaaS | Gartner defines a special subset of PaaS: high-productivity application platform as a service. These provide services for declarative, model-driven application design and development, and simplified one-button deployments. They typically create metadata and interpret it at runtime; many allow optional procedural programming extensions. The underlying infrastructure is opaque to the user — they do not deal with servers or containers directly. The rapid application development features are often referred to as "low code" and "no code" support. hpaPaaS solutions provide: UI capabilities via responsive web and mobile apps; orchestration or choreography of pages, business processes, and decisions or business rules; a built-in database; and one-button deployment |
| SaaS | One of the main architectural problems to solve is tenant isolation — on different layers — for multi-tenant systems |
| Serverless | Presented via the Serverless Compute Manifesto, and compared side by side against VMs and containers |
Cloud service taxonomy
IaaS services
| Group | Services covered |
|---|---|
| Networking | Virtual networks; internet gateway; network ACLs; security groups; load balancing; DNS; CDN |
| Storage | File & block storage; object storage; performance tiers; Azure Storage specifics |
| Compute | Instance characteristics; instance types; compute features |
PaaS services
| Group | Services covered |
|---|---|
| Application | aPaaS; API management; queues |
| Database | Relational databases; NoSQL; cache |
| Analytics | Not considered in the course |
On API management vs an API gateway — the distinction matters:
API management allows you to know the answers to questions like: who are your top developers? Are you attracting more developers? Do you know how your API traffic is trending over time? It also provides management for the entire lifecycle of the API and tools for all stakeholders — whereas an API gateway is limited to exposing information to handle requests and services.
Architecting for the cloud
Disposable resources and immutable infrastructure
With fully automated deployment methods you can replace old components with new versions to ensure your systems maintain their initial "known-good" state. Managing a fleet of instances becomes much simpler with immutable infrastructure, since there's no need to track the changes that would occur.
With immutable infrastructure you know what's running and how it behaves. Deploying updates can become routine and continuous, with fewer failures occurring in production, and all changes are tracked by your source control and CI/CD processes.
The four rules:
| Rule | Rationale |
|---|---|
| Don't modify instances in place | This is the core pattern in immutable infrastructure. Modifying server instances is difficult to successfully automate and track, and allowing it will result in manual modifications. While in theory it is possible to have policies and tools in place to keep things consistent, in practice both fail with some regularity. There is no concise and trustworthy way to know if and where you have configuration drift |
| Replace instances to update them | If nothing is changed in situ, then to introduce change we must be able to deploy new instances without affecting the customer experience. While this can be done manually it rarely works well, as humans are bad at following rote procedures consistently. Plan to automate instance replacement |
| Plan for instance and zone failures at all times | Instance failure should be a normal part of doing business — whether unintended due to bugs or other issues, or intentional in order to perform component replacements. Zone failures on AWS and Google Cloud should also be relatively painless if you architect well; on Azure you'll want to use Availability Sets |
| Don't let instances get stale | Not unlike a computer, the longer an instance has been in use, the greater the chance it will have drifted from the optimal configuration. Don't run server instances for a long time |
Pets vs cattle: are you operating in the type of environment that, if one server crashes, everything goes down — a "Pet" — or are you in a scenario in which the loss of a server means that nothing happens, because the "herd" still exists and performs just as before — "Cattle"?
Automation
As failures are expected and accepted, we should design our architecture with this in mind. In order to recover quickly from a failure we have to react quickly. Another motivation to move fast in the cloud is to be able to respond quickly to any new requirement or change in the market. Fortunately several tools and strategies support these notions:
| Capability | Meaning |
|---|---|
| Auto recovery | When something goes down it should be noticed and recreated in an automated way |
| Auto scaling | Automatically scale up or down to the actual load and calling pattern |
| Observability | Our system must be fully interrogable at every time — observability is a very fundamental requirement |
| Easy experimentation | To support faster time-to-market and respond to market changes quickly, we should make experimentation easier — using frameworks that allow quick application development and deployment while meeting the requirements above |
Cascading failures
In interservice communication, one slow application instance without proper isolation can easily slow down the entire system.
The course's memorable analogy: a mailing list where somebody asked something; after a point most people weren't interested in the discussion, and somebody sent an unsubscribe request to the list — everybody started to do the same, creating a huge message flood and making the situation more serious.
Many different techniques help here — see the bulkhead and circuit breaker patterns in Module 4.
Loose coupling and application-level resilience
Interservice communication should be isolated, and resilience is implemented at the application level with a specific toolkit: bulkheading, proper timeouts — timeout deadlines matter — circuit breaking, and async libraries. These are the Module 4 patterns arriving as cloud operational necessities rather than optional refinements.
Cloud Native — and what it is not
Cloud Native is a commonly misunderstood term. The point is that Cloud Native is not about cloud and leveraging the cloud.
The term refers to software built for change, scale, resilience and manageability. It is often equated with microservices and containers, but those aren't required. Whether running in public or private clouds, a cloud-native app takes advantage of the elasticity and automation offered by the host platform.
The cloud-native approach is far more about "how" than it is about "where."
The right question is: what capabilities and practices make it economical to work in small batches, test hypotheses, and learn? The answer is capabilities like cheap application builds, safe deployments, automated management of deployments (start/stop/scale/health checking), security, distributed configuration, and traffic routing. Containers play a foundational role in implementing these capabilities and form the basis of the platforms that provide them — but the capabilities are what are important, not the containers.
The 12-factor principles that matter most here
The 12-factor methodology provides factors applicable in any language to software delivered as a service. Three of them carry most of the weight for cloud design:
| Principle | Why it matters |
|---|---|
| Stateless and share-nothing processes | Data — whether for state or other reasons — limits the ability to distribute or easily scale a process. Never design a process that expects a set of data to be persisted locally. All data should be persisted outside the process using an attached service |
| Dependencies explicitly declared and isolated | In practice this means the application is environment agnostic and doesn't expect some tool or library to exist outside what is explicitly declared |
| Config distinct from code | Anything distinct to an execution environment — development versus production credentials, connection strings, unique hostnames — stored in a config file separate from the code that uses it |
Why containers, specifically
Containers are increasingly popular because once an application is containerised it is easy to package, ship, and run anywhere. Unlike traditional virtualization, containers provide lightweight virtualization at the application level, and are therefore much better at squeezing every last ounce of available capacity.
The operationally decisive property: containers can start and stop at sub-second speeds, which makes it easy both to scale out and to recover from failures — simply by starting up new containers.
9.2 Web and Mobile
Choosing a web platform
Platform choice is best framed as a decision tree, and these are the questions worth asking:
| If the requirement is… | The answer tends to be |
|---|---|
| Just a simple website with static HTML pages, fast page configuration and customisation | Static site generators — Hugo, Jekyll, Gatsby |
| Content managed centrally but delivered to multiple client channels / different web apps | Headless CMS — Strapi, Contentful, Drupal headless |
| A conventional content-managed site | Traditional CMS — WordPress, Drupal, Joomla |
| Behaviour driven by configuration files and a custom configuration system | Dynamic websites with a custom configuration system |
Two selection criteria the course calls out explicitly, because they are architectural rather than cosmetic:
- Why security matters in the choice. Different site builders and CMS platforms provide different levels of security out of the box. Drupal has over the years earned a reputation for secure and robust performance; this is not so positive for WordPress, which attracts far more security threats and malware attacks
- Why performance matters in the choice. Different builders are built on platforms and frameworks with different performance characteristics. Some provide optimisation techniques out of the box — GZIP compression, caching. And simple static site generators are much faster than the alternatives
Micro frontends
The micro frontends approach is a great technique to divide the workload in a multi-team setup and isolate code.
The trigger condition is a frontend that has become too big to be supported as one unit, or teams that must ship independently. It is the Module 4 microservices argument — Conway's Law included — applied above the API boundary rather than below it. Fowler's article is the reference.
Choosing a mobile approach
| Approach | Definition | Fits when |
|---|---|---|
| Native | A mobile application created for one platform | Games, graphical apps, apps needing deep device capability |
| Cross-platform | The same codebase adapted to run on different platforms | Broad reach with shared logic |
| PWA | A progressive web application which has an icon on the mobile desktop and can provide other device-like capabilities | Only mobile web reach needed |
| Hybrid | An application that runs as a web application and can be wrapped as a native one | Reuse of web assets with store distribution |
SEO as an architectural concern
SEO means the process of optimising a web application so search engines can display it at the top of search results. For private application parts — e.g. the admin section — SEO should not be available.
That second sentence is the architectural instruction: indexability is a per-area decision, not a site-wide one, and private areas must be excluded deliberately.
The web performance metrics worth putting into a performance ASR for a front end: First Contentful Paint · Speed Index · Time to Interactive · First Meaningful Paint · First CPU Idle · Max Potential First Input Delay · Critical Rendering Path Length.
9.3 Cache
High availability for a cache means the ability to continue operating despite the failure of members of the cluster. Applied to distributed caching, HA means uninterrupted, consistent data access.
Eviction algorithms
The choice of eviction policy is an architectural decision driven by the access pattern, and getting it backwards is a classic mistake.
| Algorithm | Behaviour | Cost and best fit |
|---|---|---|
| LRU — Least Recently Used | Discards the least recently used items first | Requires keeping track of what was used when, which is expensive if you must guarantee the truly least-recently-used item is discarded. Implementations keep "age bits" per cache line, and every time a cache line is used the age of all other cache lines changes. LRU is actually a family — members include 2Q (Johnson and Shasha) and LRU/K (O'Neil, O'Neil and Weikum) |
| LFU — Least Frequently Used | Counts how often an item is needed; those used least often are discarded | Suits stable popularity distributions |
| MRU — Most Recently Used | Discards, in contrast to LRU, the most recently used items first | Chou and DeWitt (11th VLDB conference): "When a file is being repeatedly scanned in a Looping Sequential reference pattern, MRU is the best replacement algorithm." Later researchers (22nd VLDB) noted that for random access patterns and repeated scans over large datasets — cyclic access patterns — MRU has more hits than LRU because of its tendency to retain older data. Most useful where the older an item is, the more likely it is to be accessed |
| Random replacement | Randomly selects a candidate item and discards it when space is needed | Requires keeping no information about access history at all. For its simplicity it has been used in ARM processors |
The MRU result is the one worth remembering, because it is counter-intuitive: under a looping sequential scan, LRU evicts exactly the pages you are about to need again, and MRU wins. Cache policy must follow the access pattern, not habit.
9.4 Data, AI and ML
Big data characteristics
| V | Meaning |
|---|---|
| Volume | With every year, the meaning of what big data is changes |
| Variety | Digitally sourced data has variety in that it is collected with varying degrees of structure. Data can be heavily unstructured — audio, video and social media posts. A company can gather more structured data on customers' clicks on its website, or a person can track heart rate and physical activity with a wearable — but data must then be organized in order to be useful. Multi-structured data can involve combinations of structured and unstructured data, organized by similar attributes |
| Velocity | Increasingly, businesses have stringent requirements from the time data is generated to the time actionable insights are delivered to users. Therefore data needs to be collected, stored, processed and analyzed within relatively short windows — ranging from daily to real-time |
Major cloud providers enable processing of huge volumes of data on demand, and every year data processing frameworks are updated and capabilities added.
Using an RDBMS for huge volumes is not recommended — but there are plenty of cases where it was done. One documented case scaled PostgreSQL to 1.2bn records per month.
Data forms
In order to work efficiently with data we have to understand data content.
| Form | Characteristics |
|---|---|
| Structured | Highly organized information that uploads neatly into a relational database — think traditional row database structures — lives in fixed fields, and is easily detectable via search operations or algorithms. Relatively simple to enter, store, query and analyze, but it must be strictly defined in terms of field name and type (alpha, numeric, date, currency), and as a result is often restricted by character numbers or specific terminology. Analysts typically use SQL |
| Unstructured | May have its own internal structure but does not conform neatly into a spreadsheet or database. While unruly in nature it is also incredibly valuable and increasingly available in the form of complex sources: web logs, images, video, email, customer service interactions, sales automation, social media. Most business interactions, in fact, are unstructured in nature. The fundamental challenge is that these sources are difficult for non-technical business users and data analysts alike to unbox, understand and prepare for analytic use. Beyond structure there is the sheer volume — because of this, current data mining techniques often leave out valuable information and make analyzing unstructured data laborious and expensive |
| Semi-structured | Maintains internal tags and markings that identify separate data elements, which enables information grouping and hierarchies. Both documents and databases can be semi-structured. This type represents only about 5–10% of the structured/semi-structured/unstructured data pie, but has critical business usage cases |
File formats
Multiple storage formats are suitable for HDFS — plain text, rich formats like Avro and Parquet, Hadoop-specific formats like sequence files — each with pros and cons depending on use case. Classify them into two simple categories: raw data formats and processed data formats.
The access patterns differ, and so the formats should differ. For processing raw data we usually use all the fields, so the underlying storage must support that efficiently. But we access only a few columns of processed data in analytical queries, so the storage should handle that in the most efficient way in terms of disk I/O.
Raw data formats
| Format | Notes |
|---|---|
| Plain text file | A very common Hadoop use case is storing log files or other plain text files with unstructured data. These text files could easily eat up whole disk space, so proper compression is required depending on use case |
| Structured text data | More sophisticated text files having data in a standardized form — CSV, TSV, XML or JSON |
| Binary files | Images, videos stored as-is |
| Avro | Language-neutral data serialization. Avro-formatted data can be described through a language-independent schema, so it can be shared across applications using different languages. Avro stores the schema in the header of the file, so data is self-describing. Avro files are splittable and compressible, making it a good candidate for Hadoop storage. Schema evolution — the schema used to read an Avro file need not be the same as the schema used to write it, making it possible to add new fields. The schema is usually written in JSON, and can be generated from Java POJOs using Avro-provided utilities |
Processed data formats
| Format | Notes |
|---|---|
| Columnar formats (general) | They eliminate I/O for columns that are not part of the query, so they work well for queries requiring only a subset of columns. They provide better compression because similar data is grouped together |
| Parquet | A columnar format. Well suited for data warehouse kind of solutions where aggregations are required on certain columns over a huge set of data. Provides very good compression — up to 75% when used with compression formats like snappy. Can be read and written using the Avro API and Avro Schema. Also provides predicate pushdown, further reducing disk I/O cost |
| ORC | The other columnar option named |
Columnar vs row formats — Parquet vs Avro. Columnar formats are generally used where you need to query only a few columns rather than all the fields in a row, because their column-oriented storage pattern suits that. Row formats are used where you need to access all the fields of a row. So generally Avro is used to store the raw data, because during processing usually all the fields are required.
Compression. Big data solutions should process large amounts of data in quick time. Compressing data speeds up I/O operations and saves storage space — but this could increase processing time and CPU utilization because of decompression. So balance is required: more compression means smaller data size but more processing and CPU utilization.
Compressed files should also be splittable to support parallel processing. If a file is not splittable it means we cannot input it to multiple tasks running in parallel — and hence we lose the biggest advantage of parallel processing frameworks.
From data to insight
| Level | Definition |
|---|---|
| Data | The representation of facts as text, numbers, graphics, images, sound or video. Technically data is the plural of the Latin datum meaning "a fact", though people commonly use the term as singular. Facts are captured, stored and expressed as data. Data is the raw material we interpret as data consumers to continually create information. Data is always right |
| Information | Data that has been "cleaned" of errors and further processed in a way that makes it easier to measure, visualize and analyze for a specific purpose. Depending on that purpose, processing can involve different operations — combining different sets of data (aggregation), ensuring the collected data is relevant and accurate (validation). For example, we can organize data in a way that exposes relationships between seemingly disparate and disconnected data points. By asking relevant questions about who, what, when and where, we derive valuable information. Information can be wrong |
| Knowledge | Information becomes knowledge when we get to the question of how. When we don't just view information as a description of collected facts but also understand how to apply it to achieve our goals, we turn it into knowledge. This knowledge is often the edge that enterprises have over their competitors |
| Insight | As we uncover relationships that are not explicitly stated as information, we get deeper insights. Applying data science allows us to derive historical, predictive or prescriptive insights, answering "Why did it happen?", "What is likely to happen?", "What should we do to make things happen?" |
While traditional analytics allows us to look backward and discover patterns that happened in the past, modern predictive analytics and machine learning techniques allow us to create a forward-looking ("windshield") view.
Analytics maturity
| Stage | Question | Techniques and characteristics |
|---|---|---|
| Descriptive | What happened | Analyze and summarize historical data; observed customer behaviour; non-traditional data sources such as web crawling and social listening |
| Diagnostic | Why did it happen | Identify the cause of trends and outcomes; observed customer behaviour; the same non-traditional sources |
| Predictive | What could or will happen | Predict outcomes based on the past; forward-looking view of current and future customer view; sentiment scoring; graph analysis and NLP to identify hidden relationships; dual-objective models; behavioural economics |
| Prescriptive | What should we do | Recommend right or optimal actions or decisions; real-time product and service propositions; rapid evaluation of multiple what-if scenarios; optimization of decisions or actions |
| Cognitive | How can we adapt to change | Monitor, decide and act autonomously or semi-autonomously; monitor results on a continuous basis; dynamically adapt based on changing environment and improved predictions; agent-based and dynamic simulation models |
Big data solution requirements
Scalability. The solution must be scalable — but how scalable, and to which capacity? This question can be answered by dividing data and applications into categories, creating a predictive model of capacity needs for each category based on expected growth, and aggregating the results.
Scalability is not just about the size of storage; it has wider implications. The throughput and the speed of access must be scalable. In addition, the system should be able to scale operationally — that is, to grow quite large without a huge increase in dedicated staff.
Self healing. A well-designed big data solution must accommodate component failures and heal itself without human intervention.
Hadoop
| Component | Role |
|---|---|
| Hadoop Commons | Libraries and utilities used by other Hadoop modules |
| Hadoop Clients | Libraries and utilities used to access Hadoop's components |
| HDFS — Hadoop Distributed File System | A scalable system that stores data across multiple machines without prior organization |
| YARN — Yet Another Resource Negotiator | Resource management framework for scheduling and handling resource requests from distributed apps |
| MapReduce | Software programming model for processing large sets of data in parallel; in fact a distributed application on top of YARN |
MapReduce
MapReduce architecture consists mainly of two processing stages — the map stage and the reduce stage — with an intermediate process between them doing shuffle and sorting of the mapper output. The actual MR process happens in the task tracker, and the intermediate data is stored in the local file system.
Rendering diagram…
Mapper phase. The input data splits into two components, Key and Value. The key is writable and comparable in the processing stage; the value is writable only. When a client submits input data, the job tracker assigns tasks to task trackers, and the input data gets split into several input splits — which are logical in nature. A record reader converts these splits into key-value pairs; this is the actual input data format for further processing inside the task tracker. The input format type varies from one application to another, so the programmer has to observe the input data and code accordingly. With Text input format, the key is the byte offset and the value is the entire line. Partition and combiner logic come into map coding logic only to perform special data operations. Data localization occurs only in mapper nodes.
Combiner is also called a mini reducer — the reducer code is placed in the mapper as a combiner. When mapper output is a huge amount of data it requires high network bandwidth; to solve this the reduced code is placed in the mapper as combiner for better performance. The default partition used is Hash partition.
Partitioner. A partition module plays a very important role in partitioning the data received from either different mappers or combiners. It reduces the pressure that builds on the reducer and gives more performance. A customized partition can be performed on any relevant data on a different basis or conditions. It has static and dynamic partitions, which play a very important role in Hadoop as well as Hive. The partitioner splits the data into a number of folders using reducers at the end of the map reduce phase, and runs between mapper and reducer. It is very efficient for query purposes.
Intermediate process. The mapper output undergoes shuffle and sorting. The intermediate data is stored in the local file system without having replications in Hadoop nodes. This is data generated after computations based on certain logic. Hadoop uses a Round-Robin algorithm to write the intermediate data to local disk.
Reducer phase. Shuffled and sorted data passes as input to the reducer. In this phase all incoming data combines and the same actual key-value pairs get written into HDFS; a record writer writes data from reducer to HDFS. The reducer is not mandatory for searching and mapping purposes. Options are provided to set the number of reducers for each job — in mapred-site.xml you set properties enabling the number of reducers for a particular task.
Speculative execution plays an important role during job processing: if two or more mappers are working on the same data and one mapper is running slow, the job tracker assigns tasks to the next mapper to run the program fast. The execution is FIFO.
YARN
Individual machines are known as nodes; a cluster can have as few as one node or as many as several thousand. There are two types of node — ResourceManager (RM) and NodeManager (NM).
ResourceManager manages the cluster resources.
- A cluster can have only one RM — but it is not a single point of failure, because RM has an HA option
- The Active RM has a twin: a Standby RM
- Scheduler — allocates and assigns resources to applications
- Application Manager (AsM) — manages, i.e. starts/monitors/stops, the Application Masters (AM) on NodeManagers
NodeManager runs application containers, where AMs are injected, plus tasks on nodes.
- A cluster can have many NMs; more NMs means better performance (scale-out)
- It is the per-machine slave, responsible for launching the applications' containers, monitoring their resource usage — CPU, memory, disk, network — and reporting the same to the RM
ApplicationMaster manages the lifecycle for each application, negotiates resources from the RM, and works with the NM(s) to execute and monitor the tasks.
- It is, in effect, a framework-specific entity
- It has responsibility for negotiating appropriate resource containers from the Scheduler, tracking their status and monitoring for progress
- From the system perspective, the ApplicationMaster itself runs as a normal container
YARN's fundamental idea is to distinguish two major responsibilities of the distributed processing system into separate roles: a global ResourceManager and a per-application ApplicationMaster. The RM is the ultimate authority that arbitrates resources among all the applications in the system.
YARN is a framework — engine plus API, written in Java — and an abstraction: a unified data processing system, not only for MapReduce but also for Spark, Tez and others. YARN can cooperate with HDFS to get data locality information to optimize task processing.
HDFS
HDFS is the primary storage system of Hadoop. It stores very large files, running as a sequence of blocks, on a cluster of commodity hardware — all blocks in a file except the last are the same size. It follows the principle of storing a smaller number of large files rather than a huge number of small files. It stores data reliably even in the case of hardware failure, and provides high-throughput access by accessing in parallel.
| Node | Role |
|---|---|
| NameNode | Works as Master in the cluster. Stores meta-data — number of blocks, replicas and other details — present in memory in the master. Maintains and manages the slave nodes and assigns tasks to them. It should be deployed on reliable hardware as it is the centerpiece of HDFS |
| DataNode | Works as Slave in the cluster. Responsible for storing the actual data. Performs read and write operations as per client requests. Can be deployed on commodity hardware |
Critical operational facts:
- The NameNode daemon must be running at all times
- If the NameNode stops, the cluster becomes inaccessible
- The NameNode stores all metadata: file locations in HDFS; file ownership and permissions; names of the individual blocks; locations of the blocks
Metadata persistence mechanics:
- A point-in-time snapshot of the filesystem's metadata is stored in a file called fsimage
- Metadata is stored on disk and read when the NameNode daemon starts up
- Fsimage is efficient to read, but inefficient to update
- When changes to metadata are required, these are made in RAM, and changes are also written to a log file on disk called edits
- When the NameNode is running, all metadata is held in RAM for fast response
NameNode High Availability
Since the NameNode in Hadoop 1.0 provided a single point of failure for the entire cluster, the Hadoop 2.0 architecture supports multiple NameNodes to remove this bottleneck. NameNode High Availability comes with support for a Passive Standby NameNode, and these Active-Passive NameNodes are configured for automatic failover.
The HA architecture allows two NameNodes in an active/passive configuration, running at the same time. If one goes down the other takes over responsibility, reducing cluster downtime. The standby NameNode serves the purpose of a backup NameNode — unlike the Secondary NameNode — incorporating failover capabilities. With the standby node we can have automatic failover whenever a NameNode crashes (unplanned), or a graceful, manually initiated failover during a maintenance period.
Two issues in maintaining consistency:
- Active and Standby should always be in sync with each other — they should have the same metadata. This allows restoring the cluster to the same namespace state where it crashed, providing fast failover
- There should be only one active NameNode at a time, because two active NameNodes will lead to corruption of the data. This scenario is termed split-brain — a cluster gets divided into smaller clusters, each believing it is the only active cluster. To avoid such scenarios, fencing is done. Fencing is the process of ensuring that only one NameNode remains active at a particular time
Failover types:
- Graceful failover — we manually initiate the failover for routine maintenance
- Automatic failover — initiated automatically in case of NameNode failure, an unplanned event
The mechanisms that make it work:
| Component | Role |
|---|---|
| JournalNodes | In order for the Standby to keep its state synchronized with the Active, both nodes communicate through a group of separate daemons called JournalNodes. The file system journal logged by the Active NameNode at the JournalNodes is consumed by the Standby to keep its file system namespace in sync with the Active |
| DataNode dual reporting | To provide fast failover it is also necessary that the Standby have up-to-date information of the location of blocks. DataNodes are configured with the location of both NameNodes and send block location information and heartbeats to both NameNode machines |
| Apache ZooKeeper | Provides the automatic failover capability. It maintains small amounts of coordination data, informs clients of changes in that data, and monitors clients for failures. ZooKeeper maintains a session with the NameNodes; in case of failure the session expires and ZooKeeper informs other NameNodes to initiate the failover process. A passive NameNode can then take a lock in ZooKeeper stating that it wants to become the next Active NameNode |
| ZKFC — ZooKeeper Failover Controller | Responsible for HA monitoring of the NameNode service and for automatic failover when the Active is unavailable. There are two ZKFC processes — one on each NameNode machine. ZKFC uses the ZooKeeper service for coordination in determining which is the Active NameNode and when to failover |
| QJM — Quorum Journal Manager | In the NameNode, writes file system journal logs to the journal nodes. A journal log is considered successfully written only when it is written to a majority of the journal nodes, and only one of the NameNodes can achieve this quorum write. In the event of a split-brain scenario this ensures the file system metadata will not be corrupted by two active NameNodes |
In an HA setup, HDFS clients are configured with a logical name service URI and the two NameNodes corresponding to it. The clients perform source-side failover: when a client cannot connect to a NameNode, or if the NameNode is in standby mode, it fails over to the other NameNode.
Hive
The problem it solves:
Hadoop is a great solution for Big Data. You just dump everything into a distributed fault-tolerant storage, write a bunch of code to process the data in various ways, and reliably save the results back into the storage. But what if you are not a Hadoop programmer, or just don't have time to write those low-level jobs? And you actually need some advanced possibilities which Spark SQL does not provide? You are already familiar with SQL syntax and would like to use that knowledge to query and analyze the hundreds of gigabytes of data collected in your distributed storage. Then Apache Hive is the right tool for you.
Hive is an open-source data warehouse system built on top of Hadoop for querying and analyzing large datasets. It abstracts the complexity of Hadoop, provides easy-to-use SQL-like syntax called HiveQL, and enables users to do ad-hoc querying, summarization and data analysis. Hive implicitly converts HiveQL statements into a directed acyclic graph of MapReduce, Tez, or Spark jobs which are submitted to Hadoop for execution.
It also supports advanced features — indexes, partitions, buckets, ACID transactions, custom User Defined Functions, joins, sampling and many others. Many of them would take a considerable amount of time if implemented manually.
Since Hive runs on top of Hadoop it has the same limitations the Hadoop platform has, and cannot be used for online transaction processing. Hive is more suitable for traditional data warehousing tasks.
The basic flow: the request comes from one of many supported clients, passes through various Hive services, hits the execution layer where it gets processed by the configured execution engine, and the final results are saved to a distributed storage such as HDFS.
Thanks to the Hive Server 2 component, based on Apache Thrift, there are many ways of executing queries against Hive both locally and remotely: you can communicate with Hive from any language that supports Thrift — Python, Ruby and others — and you can access Hive via JDBC and ODBC interfaces directly.
Hive supports pluggable execution engines and currently can run queries via MapReduce, Tez, and Spark. Hive takes care of any differences and abstracts the user from implementation details — but each engine has its own strengths and weaknesses, so it is important to consider all of them before choosing the right engine for your setup. Resource management is delegated to Apache YARN.
Hive also provides pluggable distributed storage options. The default is HDFS, but Hive can work with data and Hive tables stored in many popular cloud storages — Microsoft Azure, Amazon, Google and others.
Components
| Component | Role |
|---|---|
| UI | The user interface to submit queries and commands. CLI — a command line interface for direct interactive and non-interactive access; the CLI only supports an embedded server and cannot be used to access a remote Hive server; it is being replaced by Beeline CLI, which supports remote access over Thrift. REST API — WebHCat, an HCatalog REST API allowing access to Hive through HTTP. Prior to Hive 2.2.0 there was also a web-based GUI, but it is no longer supported |
| Hive Server 2 | Built on Apache Thrift, hence also called a Thrift server. Allows different clients to submit requests over TCP or HTTP and retrieve the final result. This is the second generation: it supports multi-client concurrency and authentication, and was designed to provide better support for open API clients like JDBC and ODBC. It also includes a Jetty Web Server providing a web interface for configuration, logging, metrics and active session information |
| Hive Driver | Responsible for managing the lifecycle of a HiveQL statement. It also maintains session handles and statistics. It communicates with: Compiler — query parsing, type checking and semantic analysis, invoked by the driver upon receiving a HiveQL statement; Optimizer — produces the optimized logical plan in the form of a DAG of jobs; Executor — execution of jobs against Hadoop |
| Metastore | The central repository of Apache Hive metadata. Provides data abstraction and data discovery. Hive takes care of keeping both the data and the metadata in sync. It stores the system catalog and metadata about tables, columns, partitions and other information in a relational database |
Metastore modes
| Mode | Description |
|---|---|
| Embedded | By default the Metastore runs in the same JVM as the Hive service and uses an embedded Derby database stored in a local file system. In embedded mode only one Hive session can be opened at a time. For experimental purposes only |
| Local | The Hive metastore service runs in the same process as the main HiveServer process, but the metastore database runs in a separate process and can be on a separate host |
| Remote | The Hive metastore service runs in its own JVM process. The main advantage over Local mode is that Remote mode does not require the administrator to share JDBC login information for the metastore database with each Hive user |
The embedded Derby database can be optionally replaced by many other relational databases — MySQL, MS SQL Server, Oracle, Postgres.
Data units, from larger to more granular: Databases → Tables → Partitions → Buckets.
| Unit | Definition |
|---|---|
| Database | A catalog of tables. Its primary function is to provide namespacing for tables and prevent naming conflicts |
| Table | Similar to tables in relational databases — an organized set of records which have the same schema, providing the means of attaching structure to data stored in distributed HDFS |
Two types of table: internal/managed and external. They are created in a similar way; the difference is that to create an external table you must provide its location. External tables are created from data located outside of the Hive managed directories — and after removing such tables only the metadata is deleted; the data remains untouched. On the other hand, if you delete an internal table, both the data and the metadata will be permanently deleted.
Partitions and buckets. As data in HDFS storage grows bigger it gets slower and slower to query. Hive provides two main mechanisms to divide the data into multiple chunks to speed up update and retrieval.
Partitions separate the data by the values of one or more columns. Hive physically creates multiple directories for each partition, so partitions are not part of the values written to a table. For example you can partition your data by year or by user identifier; then, querying records for a specific year, only the files inside that year's directory will be scanned, skipping all other partitions — which is a major performance improvement. Each table can have one or more partitions. If you write data to a partitioned table you have to provide partitions in the insert statement. If multiple values are defined in PARTITIONED BY they will be created as a hierarchy of partition directories.
The id column is defined as a regular column and the two others are configured in the PARTITIONED BY statement. After inserting data into different partitions, the HDFS directory layout has test as the table directory with a nested directory for each partition inside it.
Before trying dynamic partitioning, set two Hive settings:
The first enables dynamic partitioning — the default value depends on the Hive version — and the second enables nonstrict mode. By default Hive requires at least one partition in the insert command to be static; switching to nonstrict mode allows all partitions to be dynamic.
Hive supports two partitioning strategies, selected while inserting the data using the PARTITION keyword. If the partition does not exist it will be created automatically.
| Strategy | Behaviour |
|---|---|
| Static | You need to run an insert statement for each partition separately and provide the hard-coded name of the partition in each insert. To insert into multiple partitions you run multiple insert queries. You need to know what data you are loading and select the right partition for it — but make sure that you are filtering the source data by the same values so that only the right data gets into the partition. The partitioning values are hard-coded in the insert, and both partition columns are omitted from the SELECT as they are already provided in the PARTITION function; if you selected them from the source table Hive would not insert any data, because there are no such columns in the target table |
| Dynamic | Run a single statement to insert all records; Hive automatically determines the correct partition for each record based on the inserted value. The drawback: it can potentially create a large number of partitions, so you need to use it carefully. Several configuration parameters control dynamic partitioning, including the maximum number of automatically created partitions. Here you add the partition columns to the SELECT, and the order of the columns in the SELECT is important — the values for partitions must come last and in the same order as they are defined in the PARTITION function |
| Dynamic-mixed | Some partition columns specified statically (e.g. country) and others dynamically (e.g. state) |
Buckets can divide tables or partitions further based on the hash function of a column or multiple columns in a table. Unlike partitions, where each partition creates a directory in HDFS, each bucket is created as a file — one file per bucket.
Partitioning the table is not required — you can create buckets even without creating partitions, for example for fast sampling (extraction of a small subset of data for local processing or other needs), or to perform efficient map-side joins.
Even while using partitions, the partitions might still be too big — buckets let you subdivide them further.
How to declare them. Specify the bucketing columns in a CLUSTERED BY statement at table creation and add INTO x BUCKETS to set the total number. If you also configure partitions, that is the number of buckets in each partition.
The rules that bite:
- The number of buckets starts from 1, but the automatically created file names start from 0
- You must select an existing column for bucketing
- If your table is partitioned you cannot use a
PARTITIONED BYcolumn as aCLUSTERED BYcolumn. The reason is precise: partition columns are not table columns — they are just directories on disk, so bucketing on them would make no sense - Buckets are created from actual values only
- You may optionally sort values inside each bucket
How a record's bucket is chosen. Hive takes a hash of the column or columns given in the table definition, and the hash function depends on the type of the column.
If all records have the same value in that column, all of them go to the same bucket — so make sure the values are distinct enough to get a well-distributed result. Bucketing on a low-cardinality column is a silent way to build one enormous file and 31 empty ones.
The example, traced through. Insert three users: Bob, Alice and Frank. Bob and Alice share the role "Engineer" so they land in the same bucket, and because the table declared SORTED BY (name), Alice is the first record in the file. Without SORTED BY they would be stored in insert order and Bob would be first. Frank has role "Manager" and is saved to a different bucket. The result in HDFS: users is the main directory containing the partition directories, and Hive created two bucket files for the three records.
Hive data types
Hive's types are very similar to SQL — numeric, date/time, string, boolean — plus some special ones worth knowing:
| Type | Notes |
|---|---|
| INTERVAL | Support for intervals of time units: year-to-month intervals, day-to-second intervals, intervals with constant numbers. Also timeunit aliases — SECONDS / MINUTES / HOURS / DAYS — to aid portability and readability |
| STRUCT | Elements within the type are accessed using DOT (.) notation |
| UNION | Can at any one point hold exactly one of its specified data types. The value is tagged with a zero-indexed integer representing which type it currently holds |
Apache Spark
Spark is an open-source cluster-computing framework designed for speed and ease of use, and it has been marked out as the successor to Hadoop MapReduce.
A misconception to clear up first:
Spark is well known for its in-memory performance, but that has also given rise to misconceptions about its on-disk abilities. Spark is in fact a general execution engine — with greatly improved performance both in-memory as well as on-disk, compared with older frameworks like MapReduce.
What makes it attractive architecturally:
- Highly accessible — APIs for Scala, Java, Python, R and SQL
- A large set of integrated libraries — machine learning, SQL, streaming
- It competes with MapReduce, not with the entire Hadoop ecosystem. For example, Spark does not have its own distributed filesystem, but can use HDFS
Why it is faster — the mechanism, not the marketing:
| Engine | How it processes |
|---|---|
| MapReduce | A batch-processing engine operating in sequential steps: read data from the cluster → perform its operation → write the results back to the cluster → read the updated data → perform the next operation → write those results back → and so on |
| Spark | Performs similar operations, but in a single step and in memory: reads data from the cluster → performs its operation → writes it back to the cluster |
So the speed comes from not round-tripping through the cluster between every stage. Spark can also use disk when it must — which is exactly why the "in-memory only" framing is misleading.
9.5 Message-Oriented Middleware
Using a MOM system, a client makes an API call to send a message to a destination managed by the provider. The call invokes provider services to route and deliver the message.
Channels, also known as queues, are logical pathways that connect the programs and convey messages. A channel behaves like a collection or array of messages — but one that is magically shared across multiple computers and can be used concurrently by multiple applications.
Message Brokers are a subset of MOM. Brokerless solutions are another subset. Messaging tends to concentrate on the reliable exchange of messages around a network, using queues as a reliable load balancer and topics to implement publish and subscribe.
An ESB can be used as MOM, however it provides a lot of other services that are out of MOM scope. An ESB typically adds features beyond messaging such as orchestration, routing, transformation and mediation.
Three corrections the module makes explicitly:
- First, it's better to use load balancers for balancing the load, not a message queue. Anyway, if messages are arriving at a queue faster than the consumer can process them, we can start multiple instances of the consumer process and the message broker will "balance the load" by distributing the messages to all available consumers in round-robin fashion
- A message queue, as an architecture element, can be configured for high reliability and availability — cluster, mirroring, guaranteed delivery
- The same scenario with several consumers: a correctly designed event-driven architecture can be performant
Standards
AMQP
AMQP stands for Advanced Message Queuing Protocol.
- A binary, application-layer protocol (wire-level)
- Does not have a standard API
- Open standard: ISO/IEC 19464
- A lot of brokers implement it and there are a lot of native clients
History: AMQP was originated in 2003 by John O'Hara at JPMorgan Chase in London. In 2005 JPMorgan Chase approached other firms to form a working group, which grew to 23 companies over the next years. Previous versions were 0-8 (June 2006), 0-9 (December 2006), 0-10 (February 2008) and 0-9-1 (November 2008) — and these earlier releases are significantly different from the 1.0 specification.
Exchange types
| Exchange | Routing behaviour |
|---|---|
| Direct | Messages are routed to the queues whose binding key exactly matches the routing key of the message. The default exchange is a pre-declared direct exchange with no name, usually referred to by the empty string "". When you use the default exchange, your message is delivered to the queue with a name equal to the routing key of the message — because every queue is automatically bound to the default exchange with a routing key the same as the queue name |
| Fanout | Routes messages to all of the queues bound to it. Using it we can implement the "Topic" pattern, where each consumer listens to its own queue. The fanout copies and routes a received message to all bound queues regardless of routing keys or pattern matching — keys provided will simply be ignored |
| Topic | Does a wildcard match between the routing key and the routing pattern specified in the binding |
JMS
Java Message Service (JMS) API. Versions: 1.0.2B (June 26, 2001), 1.1 (April 12, 2002), 2.0 (May 21, 2013).
- The JMS specification was originally developed to allow Java applications access to existing MOM systems. Since its introduction it has been adopted by many existing MOM vendors, and has been implemented as an asynchronous messaging system in its own right
- In JMS, APIs are specified, but the message format is not. Unlike AMQP, JMS has no requirement for how messages are formed and transmitted. Essentially, every JMS broker can implement the messages in a different format. They just have to use the same API
- The single biggest change in JMS 2.0 is a new API for sending and receiving messages that reduces the amount of code a developer must write
JMS elements
| Element | Definition |
|---|---|
| JMS provider/broker | An implementation of the JMS interface for message-oriented middleware. Providers are implemented as either a Java JMS implementation or an adapter to a non-Java MOM |
| JMS client | An application or process that produces and/or receives messages |
| JMS producer/publisher | A JMS client that creates and sends messages |
| JMS consumer/subscriber | A JMS client that receives messages |
| JMS message | An object that contains the data being transferred between JMS clients |
| Destinations | JMS queue or topic |
Others
STOMP and MQTT are also covered.
Message brokers
A message broker is an intermediary computer program module that translates a message from the formal messaging protocol of the sender to the formal messaging protocol of the receiver. A message broker may support several additional actions.
Persistence. A message can be published either with a delivery mode set to persistent or transient.
Background: both persistent and transient messages can be written to disk. Persistent messages will be written to disk as soon as they reach the queue, while transient messages will be written to disk only so that they can be evicted from memory while under memory pressure. Persistent messages are also kept in memory when possible, and only evicted under memory pressure.
How the queue handles this: when a message enters the queue, the queue needs to determine if the message should be persisted. If so, it does so right away. Now, even if a message was persisted to disk, this doesn't mean the message got removed from RAM — a cache of messages in RAM is kept for fast access when delivering to consumers. Whenever we talk about paging messages out to disk, we are talking about what happens when messages must be sent from this cache to the file system.
Implementations — open-source, proprietary and cloud-oriented; the list is not exhaustive: Apache ActiveMQ, Apache Kafka, Apache Qpid, Celery, Fuse Message Broker, HornetQ, IBM WebSphere MQ, Oracle Advanced Queuing, Microsoft Message Queuing, Simple Queue Service, StormMQ, IronMQ, Tarantool, Joram, Azure Service Bus, NATS, Open Message Queue, Oracle Message Broker, QDB, RabbitMQ, WSO2 Message Broker.
In addition, hardware-based messaging middleware exists, with vendors like Solace Systems, Sonoa/Apigee and Tervela offering queuing through silicon or silicon/software datapaths.
RabbitMQ
- Open source
- Written in Erlang and built on the OTP (Open Telecom Platform)
- Part of Pivotal company since 2013
- Extensible plug-in architecture
- Multiple protocols
Clustering and mirroring. Typically you would use clustering for high availability and increased throughput, with machines in a single location.
By default, queues within a RabbitMQ cluster are located on a single node — the node on which they were first declared. This is in contrast to exchanges and bindings, which can always be considered to be on all nodes.
Queues can optionally be made mirrored across multiple nodes. Each mirrored queue consists of one master and one or more mirrors, with the oldest mirror being promoted to the new master if the old master disappears for any reason.
Messages published to the queue are replicated to all slaves. Consumers are connected to the master regardless of which node they connect to, with slaves dropping messages that have been acknowledged at the master.
Queue mirroring therefore enhances availability but does not distribute load across nodes — all participating nodes each do all the work.
Apache Kafka
Kafka is built on the concept of a transaction log. In databases, a transaction log — also transaction journal, database log, binary log or audit trail — is a history of actions executed by a DBMS to guarantee ACID properties over crashes or hardware failures. Physically, a log is a file listing changes to the database, stored in a stable storage format.
A topic is a category or feed name to which messages are published. For each topic, the Kafka cluster maintains a partitioned log. Each partition is an ordered, immutable sequence of messages that is continually appended to a commit log.
Topics in Kafka are always multi-subscriber — a topic can have zero, one, or many consumers that subscribe to the data written to it.
The Kafka cluster retains all published messages — whether or not they have been consumed — for a configurable period of time.
In fact the only metadata retained on a per-consumer basis is the position of the consumer in the log, called the "offset". This offset is controlled by the consumer: normally a consumer will advance its offset linearly as it reads messages, but the position is controlled by the consumer and it can consume messages in any order it likes. For example, a consumer can reset to an older offset to reprocess.
Rendering diagram…
The partitions in the log serve several purposes. First, they allow the log to scale beyond a size that will fit on a single server — each individual partition must fit on the servers that host it, but a topic may have many partitions so it can handle an arbitrary amount of data. Second, they act as the unit of parallelism.
Each partition has one server which acts as the "leader" and zero or more servers which act as "followers". The leader handles all read and write requests for the partition while the followers passively replicate the leader. If the leader fails, one of the followers will automatically become the new leader. Each partition is replicated across a configurable number of servers for fault tolerance.
Consumer groups. Kafka offers a single consumer abstraction that generalizes queueing and publish-subscribe — the consumer group.
Consumers label themselves with a consumer group name, and each record published to a topic is delivered to one consumer instance within each subscribing consumer group. Consumer instances can be in separate processes or on separate machines.
- If all the consumer instances have the same consumer group, then the records will effectively be load balanced over the consumer instances
- If all the consumer instances have different consumer groups, then each record will be broadcast to all the consumer processes
ZeroMQ
ZeroMQ is designed to be faster, but it lacks many of the broker functions the others provide — there is no broker to lose, and no broker to rely on. Published throughput figures vary sharply with message size, so benchmark at your own payload size rather than trusting a headline number.
AWS messaging
Fully managed messaging services: Amazon SQS, Amazon SNS, Amazon Kinesis, Amazon MQ, AWS IoT Message Broker — plus AWS SES (an email service) and AWS Pinpoint (a complete customer engagement platform), which are probably beyond the module's scope but which Amazon lists among its messaging services for modern application architecture.
SQS — Simple Queue Service
Amazon SQS is a fully managed message queuing service that enables you to decouple and scale microservices, distributed systems, and serverless applications.
| Queue type | Characteristics |
|---|---|
| Standard queue | Higher throughput, at-least-once delivery, best-effort ordering |
| FIFO queue | Ordering preserved, exactly-once processing, limited throughput |
Visibility timeout — how to set it. Messages are processed at different speeds, and getting this wrong hurts in both directions.
Consider the typical scenario of processing files: we store the file to S3 and send its reference to a queue. Usually the file size is up to 100 KB — however, it's even possible to get a file up to 1 GB (a huge attachment), and processing it could take a while. With a small visibility timeout it could cascade, choking up all the threads. With a large visibility timeout it could be a very delayed failover — which is not uncommon nowadays, especially with autoscaling.
Dead-letter queues capture messages that cannot be processed successfully. Virtual queues are also supported. Lambda integrates with SQS as an event source.
Virtual queues build on the Return Address enterprise integration pattern and the temporary-queue client — worth knowing when you need request/reply semantics over a queue without provisioning a queue per requester.
SNS — Simple Notification Service
A highly available, durable, secure, fully managed pub/sub messaging service that enables you to decouple microservices, distributed systems and serverless applications.
The architecturally interesting feature is filter policies: a subscription carries a filter expressed as JSON, and SNS matches it against the message attributes of each published message, delivering only what matches. That moves routing logic out of consumers and into the messaging layer — the same concern AMQP solves with topic exchanges.
Kinesis
Amazon Kinesis makes it easy to collect, process and analyze real-time streaming data so you can get timely insights.
Two properties worth carrying into a design:
- Kinesis + Lambda have a "native" integration — you get stream processing without having to write polling code
- Kinesis Data Firehose is for loading data from a Kinesis data stream into data stores and analytics tools — the managed sink, as opposed to the stream itself
Kinesis Data Streams gained higher fan-out and faster stream reads through enhanced fan-out, which removes the shared-throughput constraint when several consumers read the same shard.
9.6 NoSQL
Why relational databases won — and why NoSQL appeared
Even though SQL databases appeared after hierarchical and network databases, they won the battle and dominated for decades as mainstream data storage. Why?
- First, the relational data model is built on a strong mathematical foundation — normalization theory
- It provides ACID guarantees on data updating and reading, which allows you to rely on data consistency
- It provides vertical scaling, which worked — and still works to some extent — well in many cases
However, not so many years ago a whole family of NoSQL databases appeared. They might be considered successors of the hierarchical and networking databases designed in the 1960s. Why?
- Because the world changed. Nowadays we have significantly increased amounts of data that can barely be handled by a single server. In addition, we want this data to be handled immediately — 20 years ago the creation of a complex report might take several hours and that was OK; now we want results immediately
- The business wants 100% availability, which can't be reached with a single server: downtimes are needed to maintain hardware, install updates, change database schemas
- In many cases we must deal with poor connections between servers and restrictions of network protocols
So we need horizontal scaling and clustering to handle these requirements. But SQL databases were not designed to work in a cluster — and the root cause is the ACID guarantees.
Scalability techniques
Two important techniques for horizontal scalability
| Technique | Detail |
|---|---|
| Partitioning (sharding) | The database can be partitioned over servers using a partitioning key that is available in nearly every transaction — to avoid sending the transaction to every server. Partitioning allows the database transaction load to be split over multiple servers, increasing the throughput of the system |
| Replication | Each partition can be replicated across at least two physical servers. Replication is useful for failure recovery, and can also provide scalability for frequently-read data because the load can be split over the replicas. But unlike partitioning, replication increases the cost of writes, so it should only be used as appropriate. And if you wait for replication to another server before transaction commit, the servers should be on the same LAN; you can do remote replication for disaster recovery, but that must be asynchronous to avoid queuing incomplete transactions |
Two important techniques for vertical scalability
| Technique | Detail |
|---|---|
| RAM instead of disk | RAM should be used to store the database. Disk should only be used for backups and possibly for logging — "disk is the new tape drive!" If the database is too big to fit in the collective RAM and SSD of all the database servers you can afford, then a conventional distributed DBMS may be a better choice |
| Minimal durability overhead | There must be minimal overhead for database durability. Durability can be guaranteed by logging to disk and doing online backups in the background. You might even let the system log to disk after the transaction completes, depending on your comfort level. Alternatively, for many applications you can achieve acceptable durability by completing the replication to another server before returning from the transaction |
When these vertical scaling techniques are used, the database system becomes CPU-limited instead of disk-limited.
Sharding approaches:
- Split data by attributes between different nodes — might help, however it is not scalable enough in many cases
- Split data by some attribute's value — good for dynamic scaling, however we should know on which server our data is
Master-slave replication
Benefits
- Analytic applications can read from the slave(s) without impacting the master
- Backups of the entire database with relatively no impact on the master
- Slaves can be taken offline and synced back to the master without any downtime
- Slaves can be cheaper than the master, in case autoscaling of slaves is available
Drawbacks
- In the instance of a failure, a slave has to be promoted to master to take over its place — no automatic failover
- Downtime and possibly loss of data when a master fails
- All writes still have to be made to the master in a master-slave design
- Each additional slave adds some load to the master, since the binary log has to be read and data copied
- Multi-master is not as simple as master-slave to configure and deploy, and data synchronization has to be rather transactional (with near-zero writes), which affects availability of data
Replication works well with sharding. A shard manager allows us to select a needed shard, and then we can select master or replica for operations — balancing our load pretty well.
The pain point here: we must design the data structure in a way that all the information we need is stored on a single shard — otherwise we have to travel through all our shards to collect data. It will kill the performance. And note that we may have more than one master on a shard for some systems.
Full replication across all nodes. Data is fully replicated across all nodes, with one primary copy accepting changes and multiple active replicas typically read-only. Such configurations can be a good fit for read-intensive workloads such as reporting, where readers can potentially connect to any server and execute their queries. By contrast, writers can connect only to the primary copy, causing a bottleneck in write-intensive workloads.
Relaxing ACID
To scale up write operations, or the number of nodes in a cluster beyond a certain point, you have to be able to relax the guarantees:
| Dropping | Effect | Examples |
|---|---|---|
| Atomicity | Lets you shorten the duration for which tables (sets of data) are locked | — |
| Consistency | Lets you scale up writes across cluster nodes | Riak, Cassandra |
| Durability | Lets you respond to write commands without flushing to disk | — |
| Isolation | Lets you expose every operation immediately to any other connection | — |
CAP theorem
The CAP theorem, also named Brewer's theorem after computer scientist Eric Brewer, states that it is impossible for a distributed computer system to simultaneously provide all three of the following guarantees.
| Guarantee | Definitions |
|---|---|
| Consistency | All nodes see the same data at the same time (Wikipedia). A client perceives that a set of operations has occurred all at once (Pritchett). Any read operation that begins after a write operation completes must return that value, or the result of a later write |
| Availability | Every operation must terminate in an intended response (Pritchett). Every request received by a non-failing node in the system must result in a response |
| Partition tolerance | The system continues to operate despite arbitrary message loss (Wikipedia). Operations will complete even if individual components are unavailable (Pritchett). The cluster continues to function even if there is a "partition" — a communications break — between two nodes |
Once your network failures split your cluster, you can continue to be available and lose consistency, OR go offline and wait until failures are restored, keeping your data consistent.
BASE
| Property | Meaning |
|---|---|
| Basically available | The system does guarantee the availability of the data as regards CAP — there will be a response to any request. But that response could still be "failure" to obtain the requested data, or the data may be in an inconsistent or changing state — much like waiting for a cheque to clear |
| Soft state | Stores don't have to be write-consistent, nor do different replicas have to be mutually consistent |
| Eventual consistency | Stores exhibit consistency at some later point — e.g. lazily at read time |
Key-value stores and Redis
A key-value database, or key-value store, is a data storage paradigm designed for storing, retrieving and managing associative arrays — a data structure more commonly known today as a dictionary or hash. Dictionaries contain a collection of objects or records, which in turn have many different fields within them, each containing data. These records are stored and retrieved using a key that uniquely identifies the record and is used to quickly find the data.
Any request for the data without the key might be a performance killer.
Redis is an open-source in-memory database project implementing a distributed, in-memory key-value store.
Persistence is achieved in two different ways:
- Snapshotting — a semi-persistent durability mode where the dataset is asynchronously transferred from memory to disk from time to time, written in RDB dump format
- AOF — since version 1.1, the safer alternative: an append-only file (a journal) that is written as operations occur
Redis supports different kinds of data structures — strings, lists, maps, sets, sorted sets, hyperloglogs and more. Redis maps keys to types of values, and an important difference between Redis and other structured storage systems is that Redis supports not only strings, but also abstract data types — including sets of strings (collections of non-repeating unsorted elements).
Document-oriented databases
Document databases are inherently a subclass of the key-value store — but the difference is the one that matters for design:
In a key-value store the data is considered inherently opaque to the database, whereas a document-oriented system relies on internal structure in the document in order to extract metadata that the database engine uses for further optimization.
Contrast with the relational model. Relational databases generally store data in separate tables defined by the programmer, and a single object may be spread across several tables. Document databases store all information for a given object in a single instance, and every stored object can be different from every other. This eliminates the need for object-relational mapping while loading data into the database.
Addressing. Documents are addressed via a unique key representing that document — a simple identifier, typically a string, a URI, or a path. The database typically retains an index on the key to speed up retrieval, and in some cases the key is required to create or insert the document.
Querying — where document stores really diverge from key-value stores. Beyond simple key-to-document lookup, a document database offers an API or query language that lets you retrieve documents based on content or metadata — for example, all documents with a certain field set to a certain value. The set of query features available, and the expected performance of those queries, varies significantly from one implementation to another, as do the indexing options.
The concrete illustration of why the metadata matters:
In theory the values in a key-value store are opaque black boxes. They may offer search systems similar to a document store, but with less understanding about the organization of the content. Document stores use the metadata in the document to classify the content — allowing them, for instance, to understand that one series of digits is a phone number and another is a postal code. This lets them search on those types of data: all phone numbers containing 555, which would ignore the zip code 55555.
MongoDB and BSON
One of MongoDB's key features is that it uses the BSON format — Binary JSON — a binary-encoded serialization of JSON-like documents used when storing documents in collections.
| Property | Consequence |
|---|---|
| Binary encoding of a JSON-like structure | Adds support for data types like Date and binary that aren't supported in plain JSON |
The _id field as primary key | Its value is usually a unique identifier type named ObjectId, generated either by the application driver or by the mongod service if the driver could not generate one |
| Internal indexability | BSON enables MongoDB to internally index and map document properties — and even nested documents |
It is designed to be more efficient than storing raw JSON, which is the reason for choosing a binary encoding in the first place.
9.7 Search
Coverage note. The Search deck is almost entirely diagrams — 47 pages yielded ~340 words. The extractable substance concerns analysis at index time, which is the conceptual core anyway:
- Stemming — "foxes" can be stemmed, reduced to its root form, to become "fox". Similarly "dogs" could be stemmed to "dog"
- Synonyms — "jumped" and "leap" are synonyms and can be indexed as just the single term "jump"
Exercises — Module 9
- Review the provided scenario
- Design and document a deployment view for the scenario, in one of the clouds — AWS, Azure or Google. You can use any notation, but mind that each cloud provides its own stencils:
- draw.io supports AWS, Azure and Google Cloud
- Lucidchart supports AWS, Azure and Google Cloud
- Cloud symbols/icons can be found on the Microsoft website and imported into Visio
- Specialised web tools focus on visualising cloud architecture — e.g. cloudcraft.co for AWS
- Calculate (estimate) your solution's availability. This part is quite complex and time-consuming if done right:
- Start from the simple case where you have single points of failure and just multiply all component availabilities:
A1 × A2 × ... × An - Add redundancy to each component where required: with m identical copies the combined availability is
1 - (1 - A1)^m - Include both infrastructure and software availability per component:
Ai × As— because each software component, service and each infrastructure node can fail - For cloud services, rely on the SLA numbers published by the provider rather than calculating from scratch — and read the exclusions at the end of the agreement, since each cloud defines "unavailability" differently
- Remember the EC2 specific: region-based, fixed 99.99% only with 2+ AZs, and the number does not increase with 3 or more zones — better requires planning different regions
- Start from the simple case where you have single points of failure and just multiply all component availabilities:
- Calculate monthly and yearly running costs
Capstone — respond to a proposal request
The capstone is a response to a request for proposal. It is the exercise that forces every earlier module to connect: business architecture feeds the requirements, the requirements feed the architecture, the architecture feeds the estimate, and the estimate feeds the commercial case.
What is expected is the technical response. A real proposal also carries sales content — case studies, references, commercial terms — which is someone else's job and is not what you are practising here.
The brief — Halcyon Standards Council
Fictional, like the case study. The particulars are invented; the shape is the shape these engagements actually take.
The customer. The Halcyon Standards Council administers a system of product and location identifiers used across supply chains. It serves roughly 180,000 member businesses across 22 industries, and its mission is to make supply chains legible: it sets the identifier standards, licenses identifier prefixes to members, and provides the education and support around them.
The domain. A member is licensed a 6–9 digit prefix. From that prefix the member derives identifiers and attaches descriptive attributes:
| Identifier | Format | Purpose |
|---|---|---|
| Product identifier | 12- or 14-digit | Identifies a product; renderable as a barcode for retail transactions |
| Location identifier | 13-digit | Identifies a physical or legal location; similar format, different attribute set |
Both are composed of prefix + a sequence of unique digits, which has a consequence worth noticing in the data model: a 9-digit prefix yields 100 distinct 12-digit product identifiers by varying the last three digits, and 1,000 distinct 13-digit location identifiers by varying the last four. Capacity is a function of prefix length, and members will ask about it.
Out of scope: member onboarding and prefix licensing. Assume a member already holds a prefix.
What to build — three modules sharing one data and system architecture on one platform:
- Create and manage product identifiers
- Create and manage location identifiers
- Access identifiers and attributes created and shared by other members
Whether these present as one application or a suite of related applications is left to you. That is an architectural decision the brief deliberately does not make, and you are expected to justify whichever you choose.
The three stated goals:
- A web-based solution that extends current functionality and improves the member experience through clearer navigation and work flow
- An architecture that supports the requirements, aligns with the Council's existing enterprise architecture, is maintainable by the Council's own staff, and is scalable and sustainable given projected growth
- Efficiencies and cost reduction for future enhancements, through a standard application framework and a scalable architecture
And a forward-looking clause that is a modifiability requirement wearing a disguise:
Future expansion may include managing and sharing data other than product and location identifiers, and extending sharing permissions down to individual field level. These are out of scope — but the design should accommodate them.
Goal 2 is the one that constrains you most, and candidates routinely miss it: maintainable by the customer's own staff rules out a technology choice the customer cannot hire for, however elegant. Goal 3 plus the expansion clause together say that cost of change, not cost of build, is the evaluation criterion.
How a proposal response is structured
The technical solution is a minority of a real response. The rest is what convinces a customer you can actually deliver it:
| Area | Typical sections |
|---|---|
| Executive summary | The whole case in non-technical language, for people who will read nothing else |
| Recommended approach | The solution in outline, before any detail |
| Solution | Architecture; integration approach per interface; data architecture; security architecture; performance and availability |
| Delivery | Roadmap and timeline; phase-by-phase approach — discovery, design, implementation and integration, transition and launch |
| Service capability | Team structure; support process; service levels; how effectiveness is measured; governance and escalation |
| Infrastructure | Hosting; environments — production and non-production; sizing |
| Management | Communication plan; project metrics and reporting |
| Commercial | Estimate, resource plan, cost, assumptions |
Two observations. The delivery phases map exactly onto Module 7, so that exercise output drops straight in. And the service capability section is where proposals are most often won or lost, because it is the part that speaks to the customer's real fear — not "can you design it" but "what happens in month fourteen".
What to reuse from each module
The capstone is deliberately the integration point. Work it in this order, and each step consumes the previous one's output:
Rendering diagram…
Write the executive summary last. It is the section the customer reads first and judges you on, and you cannot write it convincingly until everything behind it exists.
What reviewers actually reject
These are the recurring failures, and none of them are about being wrong on technology.
A weak executive summary. It is the most-read and least-worked section. After reading it the customer should be able to see that you understand their business and its current state, that the proposal covers current and future needs, and that it will land on time and on budget. Write it last, from the finished document.
Diagrams that are boxes of boxes. A high-level diagram with no interaction, no protocol, no direction of dependency communicates nothing beyond "we know the words". If a reader cannot tell who calls whom, how, and what happens when it fails, the diagram is decoration.
Components named but not described. Every architecturally significant component needs its purpose, its stack, its relations and — critically — which requirements it satisfies.
Quality attribute requirements never addressed. The most common serious defect: the ASRs are listed in one chapter and the design in another, with nothing joining them. Every high-priority scenario should be traceable to the tactic and component that delivers it.
No traceability in either direction. You should be able to start from a requirement and find the design that satisfies it, and start from a component and find the requirements that justify it. Anything with no requirement behind it is scope you invented.
An estimate that does not reconcile with the plan. Reviewers check. If development totals 400 days and the resource plan shows 260, the whole commercial case is suspect.
Case study appendix — Lumen Diagnostics
Every exercise in this course is set against one fictional case, so the practice compounds. It is written as a request for proposal, which makes it double as a worked example of the genre.
This organisation is invented. Any resemblance to a real business is coincidental. The numbers are chosen to make the arithmetic in Modules 3, 6, 7 and 9 work out, not to describe any real market.
Business context
Lumen Diagnostics operates a private diagnostic-imaging network: 180 imaging centres across four regions, working alongside roughly 600 independent partner radiology practices that take overflow and specialist studies.
Referrals arrive from clinics and physicians. Each referral must become an appointment at either a Lumen centre or a partner practice, matched on modality, urgency, patient location and price.
| Fact | Value |
|---|---|
| Studies performed per year | 4.2 million |
| Referrals received per day | ~14,000 |
| Imaging centres | 180, across 4 regions |
| Partner practices | ~600 |
| Current approach | Largely manual — phone and email between the referral desk, patients, centres and partner practices |
The manual process is the problem: it consumes referral-desk time, leaves partner capacity unused because nobody can see it, and produces no reliable utilisation data.
Project overview
Lumen wants to engage a Supplier to build a scheduling platform, delivered as a service and hosted and supported by the Supplier. It must become the single source of truth for imaging appointments, giving the referral desk, partner practices and patients a shared view of confirmed bookings.
Lumen is open to recommendations on system design to meet the objective. The Supplier should meet the requirements cost-efficiently.
Six aspects the system must account for — these are effectively the business drivers:
| Aspect | Requirement |
|---|---|
| Cost reduction | Centralised utilisation and financial reporting for day-to-day management and budgeting |
| Automation | Remove the existing manual scheduling and confirmation steps |
| Integration | Integrate with the existing referral management system, the patient identity service, and corporate single sign-on |
| Consistency | One coherent look, feel and process across every portal |
| Flexibility | A highly configurable solution that can support Lumen's growth |
| Performance | Sustain peak demand, and cope with disruption events such as a centre outage or a regional surge |
Functional requirements
Note as you read that several of these are written the way customers actually write them — loosely. Making them measurable is the Module 3 exercise.
| Area | Requirement |
|---|---|
| Availability search and prioritisation | Intelligent search across partner practice availability and manually uploaded slots, based on the referral's requirements. Prioritisation on clinical match plus custom rules set by the Scheduling Manager in the Administration Portal. Referral requirements originate in the referral management system and may be amended by the patient in the Patient Portal or by the Scheduling Manager. Prioritisation may change over time as rules change |
| Offer and confirmation workflow | Support the stages Requested → Triaged → Offered → Accepted/Declined → Confirmed → Completed → Billed, with email and SMS notification on stage change. Must allow the workflow to be changed and extended later. Alongside automated offers, support manual booking by the referral desk, capturing all details through web forms |
| Change management | Frequent synchronisation with the referral management system. New referrals, amendments and cancellations are driven by those updates. Conflicts merged according to a defined policy, with alerts to affected parties. Support manually reassigning a booking to a different centre or partner when required |
| Partner practice access | Partner practices access the system to manually upload available slots, pricing and capability details. Booking with these partners is handled manually |
| Automated partner integration | One partner group is integrated automatically through its scheduling API; all other partners are integrated manually. Preferred locations load initially from the referral system but may be amended in the Patient and Administration portals, with the ability to override them |
| Appointment consolidation | Support combining multiple studies for one patient into a single visit where clinically permitted |
| Patient Portal | View upcoming appointments with status and complete, accurate detail; confirm or decline an offered appointment; view and print confirmations; access via single sign-on; capture patient feedback and associate it with the appointment |
| Administration Portal | Lets the Scheduling Manager manage configuration, gives visibility of appointment status, and provides reporting — the front end for all administration of the system |
| Reporting | Support appointment detail, partner performance and financial reporting |
Non-functional requirements, as the customer wrote them
| Category | Requirement |
|---|---|
| Usability | Use current web technologies to deliver a clean, intuitive experience that helps users complete their task without friction |
| Usability | Work across a range of screen sizes, including phones and tablets, without degrading usability |
| Architectural | Provide a scalable, high-performing data platform capable of storing and querying large volumes of appointment and study data |
| Architectural | Keep the platform on currently supported technology versions, with periodic review of version suitability and planned upgrades |
| Architectural | Be configurable enough to absorb change in regulation, internal policy, clinical protocol or organisational structure without code changes |
| Availability and performance | Perform in line with modern expectations — routine screens should feel immediate, and large reports must not take so long as to frustrate users. Precise criteria to be agreed during design |
| Disaster recovery | Be highly available and resilient, minimising the risk of service interruption |
| Configuration management | Adopt adequate configuration management and version control across all environments and documents |
| Deployability | Employ robust procedures for promoting any change into the live environment, minimising disruption to operations |
| Scalability | Be designed so the solution can grow as the network expands |
| Data security | All authenticated traffic must use encrypted transport, TLS 1.3 or better |
| Data security | Handling and transmission of patient data must comply with applicable health-data protection regulation in each region of operation |
Read this list next to the Module 3 worked example and the whole exercise becomes visible. "Precise criteria to be agreed during design" is the customer declining to give you a number. "Current web technologies" is a constraint dressed as a usability requirement. And "configurable enough to absorb change in regulation, internal policy, clinical protocol or organisational structure" is a modifiability requirement that means nothing until somebody commits to how long a change may take — which is exactly what the worked example does when it holds the configuration team to one working day.
Growth assumptions you are expected to design for
These are stated separately because they drive the scalability and portability requirements rather than the functional ones:
- Lumen expects 12% annual growth in referral volume
- It intends to enter two further regions within three years, including one outside its current jurisdiction
- Patient-facing use is shifting to mobile — currently ~45% of patient portal sessions, and rising
- Partner practice numbers are expected to roughly double
Glossary
| Term | Definition |
|---|---|
| ASR | Architecturally Significant Requirement — a requirement with a measurable impact on architecture, whether functional or non-functional. Ultimately measured by high cost of change |
| Quality attribute | A measurable or testable property of a system indicating how well it satisfies stakeholder needs |
| NFR | Non-functional requirement — criteria used to evaluate the whole system rather than a specific behaviour |
| Constraint | A requirement that removes design freedom; almost always architecturally significant |
| Tactic | A design decision to achieve a quality attribute response, with no trade-offs considered internally. "Atoms" |
| Pattern | A design solution for a concrete context and problem, with trade-offs built in. "Molecules" |
| Style | The highest level of granularity — layers, high-level modules, their interaction and relations |
| Structure | A set of elements and their organisation |
| View | A representation of a structure, documented per a template in a chosen notation, for some stakeholders |
| Viewpoint | The conventions for constructing, interpreting, using and analysing one type of view — where you look from |
| Perspective | A collection of activities, tactics and guidelines ensuring the system exhibits a set of related quality properties. Applied to views; never produces new views |
| AD | Architecture Description — consists of one or more views, plus possibly principles, standards and glossaries |
| SAD | Software Architecture Document |
| Business driver | A resource, process or condition vital for continued business success and growth. Named with a noun |
| Business goal / objective | A goal is a general statement of desired achievement; an objective is a specific step to reach it. Both SMART |
| Business capability | What a business does now and must do to meet future challenges — the what, not the how |
| Value stream | An end-to-end collection of value-adding activities creating a result for a customer or stakeholder, using capabilities as steps |
| RACI | Responsible, Accountable, Consulted, Informed. Exactly one Accountable per activity; accountability precedes responsibility |
| Transition requirement | A capability needed only to move from current to future state, not needed once the change completes |
| Utility tree | QA → attribute refinement → prioritised ASR scenarios, each rated for business importance and difficulty to achieve (H/M/L) |
| QAW | Quality Attribute Workshop — SEI's eight-step scenario elicitation. Mini and nano variants exist |
| Six-part scenario | Source, Stimulus, Artifact, Environment, Response, Response measure |
| ADD | Attribute-Driven Design — iterative design method organised into rounds (steps 1–7) and iterations (steps 2–7) |
| ATAM | Architecture Tradeoff Analysis Method — SEI's architecture evaluation method |
| Coupling / Cohesion | Coupling is interdependence between modules; cohesion is relatedness within a module. Low coupling, high cohesion |
| SOA vs microservices | Scope: SOA is enterprise, microservices are application |
| Mediator vs broker | Event-driven topologies: mediator orchestrates multi-step events centrally; broker chains events with no central orchestration |
| Fault → Error → Failure | The fault is the defect; the error is the incorrect state liable to lead to failure; the failure is observable non-compliance with the specification, detected by users |
| Redundancy types | Spatial (copies in different places), temporal (over time, e.g. recovery blocks), informational (multiple versions of data) |
| Hot / warm / cold standby | Determines switchover speed; checkpoints help a warm standby catch up faster |
| Blue-green / canary | Zero-downtime deployment techniques. Canary is the answer when automated test coverage is low |
| CAP | Consistency, Availability, Partition tolerance — under partition you choose availability or consistency |
| BASE | Basically available, Soft state, Eventual consistency |
| Scale cube | X = cloning, Y = functional decomposition, Z = data sharding |
| Cone of uncertainty | The best-case estimate accuracy at each project point. Narrows only through project control — otherwise it becomes a cloud |
| Parkinson's Law / Student Syndrome | Why overestimation's penalty is linear and bounded, while underestimation's is nonlinear and unbounded |
| Accuracy vs precision | Independent. The precision you present should match the accuracy you actually have |
| WBS | Work Breakdown Structure — deliverable-oriented (scope) or task-oriented (work) |
| Law of Large Numbers | Why decomposed bottom-up estimates beat one big estimate: errors partly cancel |
| Wideband Delphi | Anonymous iterative group estimation; any "no" vote returns the group to discussion |
| TCO | Total Cost of Ownership — initial plus all continuing costs through final decommissioning |
| NIST five properties | On-demand self-service, broad network access, resource pooling, rapid elasticity, measured service |
| hpaPaaS | High-productivity aPaaS — declarative, model-driven, low-code/no-code, opaque infrastructure |
| Pets vs cattle | Whether losing one server takes everything down, or the herd carries on unaffected |
| Immutable infrastructure | Never modify instances in place; replace to update; plan for failure; don't let instances get stale |
| DIKW | Data → Information → Knowledge → Insight. Data is always right; information can be wrong |
| Analytics maturity | Descriptive → Diagnostic → Predictive → Prescriptive → Cognitive |
| Splittable compression | Compressed files must remain splittable or parallel frameworks lose their main advantage |
| Avro vs Parquet | Row-oriented, self-describing, schema-evolving (raw data) vs columnar with predicate pushdown (processed data) |
| Split-brain / fencing | Two active masters corrupting data; fencing ensures only one remains active |
| Consumer group | Kafka's abstraction generalising queueing (same group = load balanced) and pub-sub (different groups = broadcast) |
| AMQP vs JMS | AMQP specifies the wire format but no standard API; JMS specifies the API but not the message format |
| Visibility timeout | SQS: too small cascades and chokes threads; too large delays failover |
| Governance characteristics | Discipline, Transparency, Independence, Accountability, Responsibility, Fairness |
References and further reading
Every framework in this course traces to one of these. Where a module summarises a source, read the source — the summary is a map, not the territory.
Standards
| Source | Covers |
|---|---|
| ISO/IEC/IEEE 42010 — Systems and software engineering: Architecture description | Architecture, architecture description, view, viewpoint, model kind, stakeholder, concern. The vocabulary in Modules 1 and 6 |
| ISO/IEC 25010 — Systems and software quality models | The quality attribute taxonomy in Module 3 |
| ISO/IEC 14764 — Software maintenance | The maintenance categories in Module 7 |
| TOGAF (The Open Group) | Architecture governance, the Architecture Definition Document, the ADM phases. Modules 6 and 8 |
| ArchiMate (The Open Group) | Business-architecture modelling notation, Module 2 |
| BPMN, UML (OMG) | Notations in Module 5 |
| NIST SP 800-145 — The NIST Definition of Cloud Computing | The five essential characteristics in Module 9 |
Books
| Source | Covers |
|---|---|
| Bass, Clements & Kazman — Software Architecture in Practice | The backbone: quality attribute scenarios, tactics, architectural structures, the modifiability cost model. Modules 1, 3, 6 |
| Clements et al. — Documenting Software Architectures: Views and Beyond | View packets, the interface template, style-and-view catalogue. Module 6 |
| Rozanski & Woods — Software Systems Architecture | The seven viewpoints and the perspectives concept. Module 6 |
| Richards — Software Architecture Patterns and Fundamentals of Software Architecture | Layered, event-driven (mediator and broker), microservices. Module 4 |
| Hohpe & Woolf — Enterprise Integration Patterns | The integration vocabulary used throughout Modules 4 and 9 |
| Hanmer — Patterns for Fault Tolerant Software | Fault, error, failure; redundancy types; recovery blocks. Modules 3 and 4 |
| Evans — Domain-Driven Design | Bounded context and context mapping. Module 4 |
| Humble & Farley — Continuous Delivery | Blue-green deployment, canary release, rollback. Module 4 |
| Abbott & Fisher — Scalability Rules | The scalability rules quoted in Module 3 |
| McConnell — Software Estimation: Demystifying the Black Art | Cone of uncertainty, over- versus underestimation, decomposition, Wideband Delphi. Module 7 |
| Nygard — Release It! | Circuit breaker, bulkhead, stability patterns. Module 4 |
| Newman — Building Microservices | Service decomposition and its costs. Module 4 |
| Kleppmann — Designing Data-Intensive Applications | Replication, partitioning, consistency. Module 9 |
| Lencioni — The Ideal Team Player | The hungry / humble / people-smart model referenced in Module 7 |
Papers and technical reports
| Source | Covers |
|---|---|
| Kruchten — The 4+1 View Model of Software Architecture (IEEE Software, 1995) | Module 6 |
| Parnas — On a buzzword: hierarchical structures (1974) | The origin of multiple structures, Module 6 |
| Perry & Wolf — Foundations for the Study of Software Architecture (1992) | Module 6 |
| Chen, Ali Babar & Nuseibeh — Characterizing Architecturally Significant Requirements (IEEE Software, 2013) | The four-part ASR framework in Module 3 |
| Clements & Bass — Relating Business Goals to Architecturally Significant Requirements (CMU/SEI-2010-TN-018) | The business-goal categories in Module 3 |
| Barbacci et al. — Quality Attribute Workshops (SEI) | The QAW steps in Module 3 |
| Kazman, Klein & Clements — ATAM: Method for Architecture Evaluation (CMU/SEI-2000-TR-004) | Module 8 |
| Bachmann & Bass / Wojcik et al. — Attribute-Driven Design (SEI) | The ADD rounds and iterations in Module 8 |
| O'Brien, Bass & Merson — Quality Attributes and Service-Oriented Architectures (CMU/SEI-2005-TN-014) | The SOA maturity table in Module 3 |
| Brewer — Towards Robust Distributed Systems (2000) and the CAP follow-ups | Module 9 |
| Lientz & Swanson — Software Maintenance Management (1980) | The maintenance categories in Module 7 |
Online and freely available
| Source | Covers |
|---|---|
| c4model.com — Simon Brown | The C4 model in Module 6 |
| arc42.org | The arc42 documentation template in Module 6 |
| adr.github.io and Nygard's Documenting Architecture Decisions (2011) | Architecture decision records, Module 6 |
| 12factor.net | The twelve-factor principles in Module 9 |
| microservices.io — Chris Richardson | The scale cube and microservice patterns, Modules 3 and 4 |
| martinfowler.com | Micro frontends, the architect elevator, CQRS, strangler fig |
| Azure Architecture Center (Microsoft) | CQRS, event sourcing, sharding, gatekeeper, valet key, federated identity — Module 4 |
| OWASP Top Ten, OWASP ZAP | Module 3 |
| Microsoft STRIDE threat model | Module 3 |
| Apache project documentation — Hadoop, Hive, Spark, Kafka | Module 9 |
| AMQP (ISO/IEC 19464) and JMS specifications | Module 9 |
| Cloud provider documentation and pricing pages | Module 7 and 9 sizing and cost models |
About this course
The case study, Lumen Diagnostics, and the capstone brief, Halcyon Standards Council, are fictional. Their numbers are chosen so the arithmetic in Modules 3, 6, 7 and 9 resolves cleanly and can be checked by the reader — not to characterise any real organisation or market.
Where a section is thinner than others, that reflects where the public literature is thinner. Modules 5 and 8 are the least detailed: modelling notation is best learned by drawing rather than reading, and architecture evaluation is best learned by sitting in a review. For Module 8 in particular, go to the SEI ATAM and ADD reports directly — they are freely available and more precise than any summary.