1 00:00:00,240 --> 00:00:01,870 Okay, so in the past lecture, 2 00:00:01,870 --> 00:00:04,852 we were in a stateless type of web application, 3 00:00:04,852 --> 00:00:06,290 WhatIsTheTime.com. 4 00:00:06,290 --> 00:00:08,630 Just enter the time and we didn't need any database 5 00:00:08,630 --> 00:00:10,488 or any information, external information, 6 00:00:10,488 --> 00:00:12,300 to answer that question. 7 00:00:12,300 --> 00:00:14,250 But now we are going to get into a stateful 8 00:00:14,250 --> 00:00:16,487 web application called MyClothes.com 9 00:00:16,487 --> 00:00:19,650 And MyClothes.com allows people to buy clothes online. 10 00:00:19,650 --> 00:00:22,740 And there is a shopping cart when you navigate MyClothes.com 11 00:00:22,740 --> 00:00:25,260 and we're having hundreds of users at the same time 12 00:00:25,260 --> 00:00:27,410 so all these users are navigating the website 13 00:00:27,410 --> 00:00:28,960 and we wanna be able to scale, 14 00:00:28,960 --> 00:00:30,710 maintain horizontal scalability 15 00:00:30,710 --> 00:00:34,390 and keep our application web tier as stateless as possible. 16 00:00:34,390 --> 00:00:36,950 So even though there is a state of shopping cart, 17 00:00:36,950 --> 00:00:39,060 we want to be able to scale our web application 18 00:00:39,060 --> 00:00:40,900 as easily as possible. 19 00:00:40,900 --> 00:00:42,350 So users, that means that they should not lose 20 00:00:42,350 --> 00:00:45,150 their shopping cart while navigating our website, 21 00:00:45,150 --> 00:00:46,070 that would be really bad. 22 00:00:46,070 --> 00:00:49,350 And maybe also have their details such as address, etcetera, 23 00:00:49,350 --> 00:00:51,850 in a database that we can store effectively 24 00:00:51,850 --> 00:00:53,780 and make accessible from anywhere. 25 00:00:53,780 --> 00:00:55,420 So let's see how we can proceed. 26 00:00:55,420 --> 00:00:57,590 You'll see it's going to be yet another fun 27 00:00:57,590 --> 00:01:00,580 but challenging discussion. 28 00:01:00,580 --> 00:01:04,090 Okay, so this is our application and I'm going to go fast. 29 00:01:04,090 --> 00:01:05,680 Here's the kind of architecture we've seen 30 00:01:05,680 --> 00:01:07,070 in the previous lecture. 31 00:01:07,070 --> 00:01:10,250 So we have our user, Route 53, Multi AZ ELB, 32 00:01:10,250 --> 00:01:12,950 Auto Scaling group three AZ, very basic. 33 00:01:12,950 --> 00:01:16,507 So our application is accessing our ELB and our ELB says 34 00:01:16,507 --> 00:01:19,340 "Alright, you're gonna talk to this instance." 35 00:01:19,340 --> 00:01:20,870 And you create a shopping cart, 36 00:01:20,870 --> 00:01:22,930 and then the next request is going to go 37 00:01:22,930 --> 00:01:24,490 not to the same instance but to another instance, 38 00:01:24,490 --> 00:01:26,310 so now the shopping cart is lost 39 00:01:26,310 --> 00:01:28,750 and the user says "Oh, there must just be a little bug, 40 00:01:28,750 --> 00:01:29,830 I'm going to try again." 41 00:01:29,830 --> 00:01:32,030 So he adds something into the shopping cart 42 00:01:32,030 --> 00:01:34,230 and it gets redirected to the third instance 43 00:01:34,230 --> 00:01:36,347 which doesn't have their shopping cart. 44 00:01:36,347 --> 00:01:38,807 So basically the user is going crazy and say, 45 00:01:38,807 --> 00:01:40,720 "Wait, I'm losing my shopping cart 46 00:01:40,720 --> 00:01:42,800 every time I do something. 47 00:01:42,800 --> 00:01:45,810 This is really weird, MyClothes.com is a bad website. 48 00:01:45,810 --> 00:01:48,260 I don't wanna shop on it, it will lost money." 49 00:01:48,260 --> 00:01:49,650 So how do we fix this? 50 00:01:49,650 --> 00:01:53,100 Well, we can introduce Stickiness or Session Affinity 51 00:01:53,100 --> 00:01:56,940 and that's an ELB feature so we enable ELB Stickiness 52 00:01:56,940 --> 00:01:59,760 and now our user talks to our first instance, 53 00:01:59,760 --> 00:02:01,840 adds something into the shopping cart 54 00:02:01,840 --> 00:02:03,700 and then the second request goes 55 00:02:03,700 --> 00:02:05,980 to the same instance because of Stickiness 56 00:02:05,980 --> 00:02:08,750 and the third request also goes to the same instance 57 00:02:08,750 --> 00:02:10,110 and actually every request will go 58 00:02:10,110 --> 00:02:12,750 to the same instance because of Stickiness. 59 00:02:12,750 --> 00:02:15,590 This works really well but if an ec2 instance 60 00:02:15,590 --> 00:02:17,670 gets terminated for some reason, 61 00:02:17,670 --> 00:02:19,740 then we still lose our shopping cart. 62 00:02:19,740 --> 00:02:23,170 But there is definitely some kind of improvement here, 63 00:02:23,170 --> 00:02:26,220 thanks to Stickiness and Session Affinity. 64 00:02:26,220 --> 00:02:30,190 So now, let's look at the completely different approach 65 00:02:30,190 --> 00:02:32,500 and introduce user cookies. 66 00:02:32,500 --> 00:02:36,210 So basically, instead of having the ec2 instances 67 00:02:36,210 --> 00:02:38,510 store the content of the shopping cart, 68 00:02:38,510 --> 00:02:41,360 let's say that the user is the one storing 69 00:02:41,360 --> 00:02:44,660 the shopping cart content and so every time it connects 70 00:02:44,660 --> 00:02:47,237 to the load balancer, it basically is going to say 71 00:02:47,237 --> 00:02:51,260 "By the way, in my shopping cart I have all these things." 72 00:02:51,260 --> 00:02:53,160 and that's done through web cookies. 73 00:02:53,160 --> 00:02:55,210 So now if it talks to the first server, 74 00:02:55,210 --> 00:02:57,740 the second server or the third server, 75 00:02:57,740 --> 00:03:01,490 each server will know what the shopping cart content is 76 00:03:01,490 --> 00:03:04,430 because the user is the one sending 77 00:03:04,430 --> 00:03:08,280 the shopping cart content directly into our ec2 instances. 78 00:03:08,280 --> 00:03:09,370 So it's pretty cool right? 79 00:03:09,370 --> 00:03:12,970 We achieved stateless test because now each ec2 instance 80 00:03:12,970 --> 00:03:14,520 doesn't need to know what happened before. 81 00:03:14,520 --> 00:03:17,290 The user will tell us what happened before 82 00:03:17,290 --> 00:03:20,490 but the HTTP request, they are getting heavier. 83 00:03:20,490 --> 00:03:23,390 So because we sent the shopping cart content in web cookies 84 00:03:23,390 --> 00:03:25,590 we're sending more and more data every time 85 00:03:25,590 --> 00:03:27,850 we add something into our shopping cart. 86 00:03:27,850 --> 00:03:30,830 Additionally, there is some level of security risk 87 00:03:30,830 --> 00:03:33,020 because the cookies, they can be altered 88 00:03:33,020 --> 00:03:36,140 by attackers maybe and so maybe our user may have 89 00:03:36,140 --> 00:03:38,370 a modified shopping cart all of a sudden. 90 00:03:38,370 --> 00:03:40,960 So, when we do have this kind of architecture 91 00:03:40,960 --> 00:03:43,040 make sure that your ec2 instances 92 00:03:43,040 --> 00:03:45,940 do validate the content of the user cookies. 93 00:03:45,940 --> 00:03:49,810 And then, the cookies overall, they can only be so big. 94 00:03:49,810 --> 00:03:52,490 They can only be less than four kilobytes total 95 00:03:52,490 --> 00:03:54,030 so there's only a little information 96 00:03:54,030 --> 00:03:55,040 you can store in the cookies. 97 00:03:55,040 --> 00:03:57,880 You cannot store big data sets, okay? 98 00:03:57,880 --> 00:03:59,210 So this is the idea. 99 00:03:59,210 --> 00:04:00,560 So, this works really well. 100 00:04:00,560 --> 00:04:02,410 This is actually a pattern that 101 00:04:02,410 --> 00:04:04,620 many web application frameworks use 102 00:04:04,620 --> 00:04:06,680 but what if we do something else? 103 00:04:06,680 --> 00:04:09,690 Let's introduce this concept of server session. 104 00:04:09,690 --> 00:04:12,910 So now, instead of sending a whole shopping carts 105 00:04:12,910 --> 00:04:15,930 in web cookies, we're just going to send a session ID. 106 00:04:15,930 --> 00:04:19,200 That is just this one for the user. 107 00:04:19,200 --> 00:04:22,060 So we're gonna send this and in the background, 108 00:04:22,060 --> 00:04:24,440 we're gonna have to maybe in the ElastiCache cluster 109 00:04:24,440 --> 00:04:26,950 and what will happened is that when we send a session ID, 110 00:04:26,950 --> 00:04:28,390 we're gonna talk to ec2 instance 111 00:04:28,390 --> 00:04:30,860 and say we're going to add this thing to the cart 112 00:04:30,860 --> 00:04:34,320 and so the ec2 instance will add the cart content 113 00:04:34,320 --> 00:04:37,310 into the ElastiCache and the ID to retrieve 114 00:04:37,310 --> 00:04:40,090 this cart content is going to be a session ID. 115 00:04:40,090 --> 00:04:43,950 So when our user basically does the second request 116 00:04:43,950 --> 00:04:47,260 with the session ID and it goes to another ec2 instance, 117 00:04:47,260 --> 00:04:50,630 that other ec2 instance is able using that session ID 118 00:04:50,630 --> 00:04:54,730 to look up the content of the cart from ElastiCache 119 00:04:54,730 --> 00:04:57,390 and retrieve that session data. 120 00:04:57,390 --> 00:05:00,140 And then, for last request, the same pattern. 121 00:05:00,140 --> 00:05:01,540 The really cool thing with ElastiCache, 122 00:05:01,540 --> 00:05:04,640 remember, it is sub-millisecond performance 123 00:05:04,640 --> 00:05:07,170 so all these things happen really quickly 124 00:05:07,170 --> 00:05:08,940 and that's really great. 125 00:05:08,940 --> 00:05:12,750 An alternative, by the way, for storing session data 126 00:05:12,750 --> 00:05:14,600 we haven't seen it yet, it's called DynamoDB. 127 00:05:14,600 --> 00:05:15,800 But I'm just putting it out here 128 00:05:15,800 --> 00:05:18,100 just in case you know what DynamoDB is. 129 00:05:18,100 --> 00:05:19,680 So, it's a really cool pattern here. 130 00:05:19,680 --> 00:05:22,020 It's more secure because now ElastiCache is a source 131 00:05:22,020 --> 00:05:25,370 of truth and no attackers can change what's in ElastiCache. 132 00:05:25,370 --> 00:05:27,955 So we have a much more secure type 133 00:05:27,955 --> 00:05:30,540 of pattern and it's very common. 134 00:05:30,540 --> 00:05:33,270 So now, okay we have ElastiCache, we figured this out. 135 00:05:33,270 --> 00:05:35,080 We wanna store user data in the database, 136 00:05:35,080 --> 00:05:37,420 we wanna store the user address. 137 00:05:37,420 --> 00:05:39,950 So again, we're gonna talk to our ec2 instance 138 00:05:39,950 --> 00:05:42,660 and this time, it's going to talk to an RDS instance. 139 00:05:42,660 --> 00:05:44,490 And RDS, it's going to be great because it's 140 00:05:44,490 --> 00:05:46,690 for long term storage and so we can store 141 00:05:46,690 --> 00:05:49,820 and retrieve user data such as address, name, 142 00:05:49,820 --> 00:05:52,360 etcetera directly by talking to RDS. 143 00:05:52,360 --> 00:05:54,600 And each of our instances can talk 144 00:05:54,600 --> 00:05:56,871 to RDS and we effectively get, again, 145 00:05:56,871 --> 00:06:00,640 some kind of Multi AZ stateless solution. 146 00:06:00,640 --> 00:06:03,020 So our traffic is going great. 147 00:06:03,020 --> 00:06:04,610 Our website is doing amazing 148 00:06:04,610 --> 00:06:06,690 and now we have more and more users 149 00:06:06,690 --> 00:06:09,710 and we realized that most of the thing they do 150 00:06:09,710 --> 00:06:10,543 is they navigate the website. 151 00:06:10,543 --> 00:06:12,990 They do reads, they get product information, 152 00:06:12,990 --> 00:06:14,120 all that kind of stuff. 153 00:06:14,120 --> 00:06:15,690 So how do we scale reads? 154 00:06:15,690 --> 00:06:17,780 Well we can use an RDS Master 155 00:06:17,780 --> 00:06:19,510 which takes the writes but we can also have 156 00:06:19,510 --> 00:06:22,550 RDS Read Replicas with some replication happening. 157 00:06:22,550 --> 00:06:24,210 And so anytime we read stuff, 158 00:06:24,210 --> 00:06:25,560 we can read from the Read Replica 159 00:06:25,560 --> 00:06:28,120 and we can have up to five Read Replicas in RDS. 160 00:06:28,120 --> 00:06:31,040 And it will allow us to scale the reads of our 161 00:06:33,250 --> 00:06:34,920 RDS database. 162 00:06:34,920 --> 00:06:37,930 There's an alternative pattern called Write Through 163 00:06:37,930 --> 00:06:40,580 where we use the cache and so the way it works is that 164 00:06:40,580 --> 00:06:43,010 our user talks to an ec2 instance. 165 00:06:43,010 --> 00:06:44,497 It looks in the cache and said, 166 00:06:44,497 --> 00:06:46,290 "Do you have this information?" 167 00:06:46,290 --> 00:06:49,660 If it doesn't have it then it's going to read from RDS 168 00:06:49,660 --> 00:06:51,440 and put it back into ElastiCache 169 00:06:51,440 --> 00:06:53,690 so just this information is cached. 170 00:06:53,690 --> 00:06:55,210 And so the other ec2 instances, 171 00:06:55,210 --> 00:06:56,590 they're doing the same thing but this time 172 00:06:56,590 --> 00:06:58,000 when they talk to ElastiCache, 173 00:06:58,000 --> 00:07:00,600 they will have the information and they get a cache hit 174 00:07:00,600 --> 00:07:02,990 and so, they directly get the response right away 175 00:07:02,990 --> 00:07:04,560 because it's been cached. 176 00:07:04,560 --> 00:07:08,870 And so this pattern allows us to do less traffic on RDS. 177 00:07:08,870 --> 00:07:11,400 Basically, decrease the CPU usage on RDS 178 00:07:11,400 --> 00:07:13,380 and improve performance at the same time. 179 00:07:13,380 --> 00:07:15,890 But we need to do cache maintenance now 180 00:07:15,890 --> 00:07:17,300 and it's a bit more difficult and again 181 00:07:17,300 --> 00:07:19,720 this has to be done application side. 182 00:07:19,720 --> 00:07:21,700 So pretty awesome now, we have our application, 183 00:07:21,700 --> 00:07:23,970 it's scalable, it has many many reads 184 00:07:23,970 --> 00:07:25,510 but we wanna survive disasters, 185 00:07:25,510 --> 00:07:27,560 we don't wanna be stricken by disasters. 186 00:07:27,560 --> 00:07:28,910 So how do we do? 187 00:07:28,910 --> 00:07:31,300 Our user talks to our Route 53 188 00:07:31,300 --> 00:07:34,110 but now we have a Multi AZ ELB. 189 00:07:34,110 --> 00:07:36,750 And by the way, Route 53 is already highly available. 190 00:07:36,750 --> 00:07:38,090 You don't need to do anything. 191 00:07:38,090 --> 00:07:39,110 Well so far, a load balancer, 192 00:07:39,110 --> 00:07:40,680 we're going to make it Multi AZ. 193 00:07:40,680 --> 00:07:44,040 Our auto scaling group is Multi AZ and then RDS, 194 00:07:44,040 --> 00:07:45,920 there's a Multi AZ feature. 195 00:07:45,920 --> 00:07:48,060 The other one is going to be a standby replica 196 00:07:48,060 --> 00:07:50,530 that can just takeover whenever there's a disaster. 197 00:07:50,530 --> 00:07:52,890 And ElastiCache also has a Multi AZ feature 198 00:07:52,890 --> 00:07:54,040 if you use Redis. 199 00:07:54,040 --> 00:07:54,940 So really cool. 200 00:07:54,940 --> 00:07:57,710 Now we basically have a Multi AZ application 201 00:07:57,710 --> 00:07:59,550 all across the board and we know for sure 202 00:07:59,550 --> 00:08:04,170 that we can survive unavailabilities on in AWS going down. 203 00:08:04,170 --> 00:08:07,290 Now for security groups, we wanna be super secure. 204 00:08:07,290 --> 00:08:10,060 So maybe we'll open HTTP, HTTPS traffic 205 00:08:10,060 --> 00:08:12,230 from anywhere on the ELB side. 206 00:08:12,230 --> 00:08:14,998 For the ec2 instance side, we just wanna restrict traffic 207 00:08:14,998 --> 00:08:18,340 coming from the load balancer and maybe for my ElastiCache, 208 00:08:18,340 --> 00:08:19,770 we just wanna restrict traffic coming 209 00:08:19,770 --> 00:08:22,660 from the ec2 security group and from RDS, same thing. 210 00:08:22,660 --> 00:08:25,140 We want to restrict traffic coming directly 211 00:08:25,140 --> 00:08:27,440 from the ec2 security group. 212 00:08:27,440 --> 00:08:28,290 So, that's it! 213 00:08:28,290 --> 00:08:29,400 So now, let's just talk 214 00:08:29,400 --> 00:08:31,790 about this architecture for web application. 215 00:08:31,790 --> 00:08:34,417 So we have discussed ELB sticky sessions, 216 00:08:34,417 --> 00:08:36,710 web client for storing cookies 217 00:08:36,710 --> 00:08:38,100 and making our web app stateless 218 00:08:38,100 --> 00:08:41,480 or using maybe a session ID and a session cache 219 00:08:41,480 --> 00:08:43,890 for using ElastiCache and as an alternative, 220 00:08:43,890 --> 00:08:45,400 we can use DynamoDB. 221 00:08:45,400 --> 00:08:48,210 We can also use ElastiCache to cache data from RDS 222 00:08:48,210 --> 00:08:50,570 in case of reads and we can use Multi AZ 223 00:08:50,570 --> 00:08:52,540 to be surviving disasters. 224 00:08:52,540 --> 00:08:54,690 RDS, we can use it for storing user data, 225 00:08:54,690 --> 00:08:57,080 so more durable type of data. 226 00:08:57,080 --> 00:08:59,600 Read replicas can be used for scaling reads 227 00:08:59,600 --> 00:09:01,130 or we can also use ElastiCache 228 00:09:01,130 --> 00:09:03,520 and then we have Multi AZ for disaster recovery. 229 00:09:03,520 --> 00:09:06,260 And on top of it, Tight Security 230 00:09:06,260 --> 00:09:08,330 for security groups referencing each other. 231 00:09:08,330 --> 00:09:10,700 So this is a more complicated application 232 00:09:10,700 --> 00:09:13,500 just three tier because there's the web tier, 233 00:09:13,500 --> 00:09:16,670 the client tier, the web tier, and the database tier. 234 00:09:16,670 --> 00:09:19,810 But this is a very common architecture overall. 235 00:09:19,810 --> 00:09:24,120 And yes, it may start to increase in cost but it is okay, 236 00:09:24,120 --> 00:09:25,910 at least we know the trade-offs we're making. 237 00:09:25,910 --> 00:09:28,400 If we want Multi AZ, yes for sure we have to pay more. 238 00:09:28,400 --> 00:09:29,740 If we want to scale the reads, 239 00:09:29,740 --> 00:09:31,940 yes for sure we'll have to pay more as well. 240 00:09:31,940 --> 00:09:33,560 But it gives us some good trade-offs 241 00:09:33,560 --> 00:09:35,380 in architecture decisions that we have to make. 242 00:09:35,380 --> 00:09:38,380 So hope you liked it and I will see you in the next lecture.