[JAVA] Behind the 10-year system

This article is the 6th day article of Recruit Lifestyle Advent Calendar 2018.

@tunanosuke. I joined Recruit this year and am now developing Hot Pepper Beauty. Hot Pepper Beauty is a product that has been in service for over 10 years. While it has been a huge success as a business, it is technically full of debt. There is a background that we have prioritized the growth of products while there are few engineers in the company so far, but we are in the stage of gradually improving. I would like to introduce the back side of how such a 10-year system is now and how it is being maintained.

Current status

Table and column names are in romaji

Romaji that appears quite often. And sometimes it is omitted. For example, for the word reserved

There is an expression method such as, and even the application is returned as it is. Is it acceptable because I can still understand Romaji? Even if it can be done, omission is quite strict. However, changing here is costly and risky, so it is important to separate what can be changed from what cannot be changed, and to block what cannot be changed as close as possible. I am doing that now.

The number of columns in one table is amazing

Long sideways, long anyway ... However, when I think about RDB, I think that I often think about how to hold it sideways, so I understand my feelings. You can see the results of adding and expanding the functions. Since there are many flags and one table manages many states, the application code is also complicated by it. On the other hand, there is also a saying, "What? Normalize here", so I'm doing it while guessing various intentions.

There are many things that can be saved by this speculation, and even if there is something to be said from a detailed perspective, I can read the intention, such as why it happened or why it happened. Of course, if you have the designers and documents at that time, it would be better, but I can not do it because I came in while there were few engineers in the employees so far. So, I feel that it is still a relief to be in a state where I feel like "Well, I want to do that."

Subquery join join subquery join union

It's long vertically, it's long anyway, it's easy if you can get it once, I'll do it The functions of Hot Pepper Beauty have been expanded with the involvement of various people. As a result, the design is ad hoc and inconsistent. Therefore, it is not a data structure that maps using an O / R mapper and is ok, but it is quite difficult to take it with one SQL. The result is one liability as a slow query. It is appropriate for the current product to have a layer in which the application gently divides the SQL and maps it to the structure that suits them on the application side, and we are also preparing each one here.

Large batch

I have a batch team. In other words, there is that much. I love batches!

It's unavoidable that it's already done, but the most difficult thing is to figure out which batch affects which data. Although it is still good for reference, it is difficult to see what data is updated for what trigger. Isn't it possible that the batch in which the update process runs locks the Master DB table for a while?

API design

First of all, Hot Pepper Beauty consists of two main services.

--Hair salon --You can search and make reservations for beauty salons --Beautiful salon ――You can search and make reservations for salons such as beauty salons, relaxation, and eyelashes.

This hair and beauty have different properties and completely different domains. We are developing it as one service. As dragged by it, API endpoints often don't distinguish between hair and beauty. Since the properties are different, the required data and response data are also different for hair and beauty, so there are many hair beauty branches in the application. There are many of the same attributes in the sense of a beauty salon, but expressing different domains in one is difficult when looking to the future, isn't it? We are currently in the process of designing a clear separation here.

POST method when retrieving resources

:thinking:

In order to eliminate past debt such as replacement, it is very important to understand the history of the product and how it happened, and if you do not do that, you will not be able to improve, but sometimes it is also necessary to decide not to pursue deeply. Or. This is such a case.

A little future outlook

sda replace.png We are replacing the monolithic architecture of the past with a BFF --Backend configuration. Backend still uses Java and BFF uses Kotlin. It's important to keep the debt that cannot be converted into Backend as much as possible so that it looks simple to each product. I will post more details about this on our engineer blog in the future.

Summary

Here are just a few. There are many things like this. On the other hand, it is wonderful that it has achieved tremendous growth as a product, and I am grateful for it and will change it to an architecture that looks ahead to the future.

Recommended Posts

Behind the 10-year system
Try using the messaging system Pulsar
Implement the box ball system with Processing