Ask HN: Is it possible to have forum type community running without a database?
This question came about as I've been asked to set up a very small forum type community running on a Raspberry Pi, and the thought occurred to me that statically generated websites can handle reasonable amounts of traffic whilst using relatively small amounts of resources.
So I wondered if it is possible to run a forum type community - something along the lines of [elgg][1] or [Friendica][2] - but without the MySQL or other type of database backend?
Now I may be about to get laughed at silly for asking such a daft question, but I would genuinely like to know the answer. So, does HN think something like this is possible? And if not, could you please explain why not? And if it is possible, have you got any recommendations!
Thanks in advance. E
[1]: http://elgg.org/ [2]: http://friendica.com/
65 comments
[ 5.7 ms ] story [ 122 ms ] threadOf course, it's unlikely you'd run a forum as big as HN or Reddit on a Raspberry Pi.
The site could not be completely static, because something must be live to handle POST requests.
I'm a member of a forum that had an old system in the beginning that used plain text "database" for a very long time. Performance was fairly reasonable at 5000 visitors per day, if the daily hit counter was to be trusted. They since moved it to SQLite, which is very reliable in its own right, and now it's Postgres. It was only now that we got searching as a "feature".
The system was written originally in PHP 4.x, but they did move it to 5.x. I'm not sure what version they use now. I do know they were running ancient hardware and was up solely due to the charity of the admin.
I think there was an index file that stores new topic summaries, as there was no field for titles, when they were created.
They used microtime() as the ID, but the topics were stored by splitting it to 3 digit directories.
Seconds as 1234567890 and decimal 0.12345618 were combined to create /123/456/789/012/345618.html
There's no registration system or other way to identify the user so I believe the posts were separated by some kind of entry separator in a single file.
I think the pagination system created an array of sequential IDs and checked to see if files existed in those directories. There were no numbered links for pagination, only next/previous and if you reached the end, the next page would be blank.
There's no reason you should ever get laughed at for being curious.
So on to your answer, I'm going to be running this community at way less than 5000 visitors per day! So from what I understand, the site was run using PHP and every time somebody made a new entry a new file was created on disk with a reference to that file in the main index page. With the name of the file was based on the time it was written to disk, with some checking to make sure to avoid files with duplicate names. I assume the main index file was the front page of the site?
Have I got that right? And if so, where do you think I should take my studying to set something like this up. I mean, are there any frameworks that you know of like Jekyll for instance or would I need to learn PHP before I could set it up?
Our forum was setup so that one thread = one HTML file. Any new replies to the thread were appended to the bottom of the file right before the footer. The added benefit of this is that it was very quick to read new posts as there was no processing taking place after the post is created.
Ex: If a new thread is being created, it will generate an ID, say 140585637400000000. Now this gets translated into a path : /140/585/637/400/000000.html and a file is created there.
The body of the new thread is added to the HTML file. Any subsequent replies are added to that same file right below the previous one.
So when a visitor requests example.com/topic/140585637400000000, the script takes the last part, turns into a file path, adds a template - which has the reply form with that ID - and sends it to the user. No additional processing needed. When a new reply is made, the script builds the path again and adds it to the bottom of the same HTML file. And so on...
I think your biggest hurdle is the initial planning. Try to carefully plan this out as much as you can, but obviously you won't know what future circumstances will bring. If you build it in such a way so that the storage mechanism doesn't need to change much or at all, you should be most of the way there.
Edit: Maybe I can convince the admin to publish some of the source. You're not the only one to be interested in something similar and I think there's a real demand for lo-fi community software.
On the other hand the textboards do appear to not use a traditional RDBMS - they were running a modified version of Shiichan (http://wakaba.c3.cx/shii/shiichan ); Kareha (http://wakaba.c3.cx/s/web/wakaba_kareha ) is another popular textboard script that doesn't need a database.
you can also hold all the data in memory but when the memory is full you have to get rid of the old threads, but if your server app restarts you lose all threads
you could also use a message queue, something like firebase
Note that they are (or did? or might be?) moving to a DB format in the end, but for at least the first several years of Startup/Hacker News, it was S-expressions written to files.
Obviously that would mean that the Raspberry Pi would always need to be connected to the Internet which wouldn't believe much of a problem, but aren't there fairly significant privacy concerns with doing something like that? Or do you think it's possible to mitigate those concerns by encrypting the link to Amazon, I am only speculating wildly here while I furiously Google all of the acronyms you mentioned. :-)
Thanks!
Privacy concerns wise, Amazon and Azure and the sorts are probably way better protected than your own installation. Of course the privacy with Amazon and Azure are all clearly written in their terms of usage and privacy statements. And NSA wise, if they get into an Amazon (either politically or technically) they will easily be able to hack your own installation.
First of all, a while ago I made a serverless chat for in your browser. It's just a proof of concept, it does work however. There will be nobody there, but you can test it by opening two browser tabs or using a second device. It works in the same way that Skype works, peer to peer. It's cool, because it is in the browser. http://codepen.io/Azeirah/pen/BHnbz
Second of all, you know bitcoins, right? It has this blockchain thing. People are starting to realize the potential of the blockchain. I've seen multiple initiatives and examples of applications using the blockhain to store the data without a static database. Note however, the data is still stored somewhere, on the users' pc's!
This is not a database-less application, it is decentralized. It's still very cool however, and may have a huge influence on the internet in the future if it stabilizes.
https://eris.projectdouglas.org/ (and their github: https://github.com/project-douglas/eris)
the goddess looks at this creation and she is happy.
1. There should be a couple of predefined categories.
2. There should be a way to authenticate/authorize users.
3. There should be a way to search the previous posts.
4. There should be a facility to moderate.
Static forums
Very neat idea. All we need is a simple webserver, I am thinking, nginx that transforms and renders our posts to a user. Our first requirement that of predefined categories can be easily met by creating sub directories inside the directory that will be served. And we can avoid duplicating the pages between the sub directory (ie. a tag) and the main directory by using symbolic links[1] and configuring nginx to serve the symlinks [2]. Moderation of posts can be done by migrating a post in and our of a `moderate` folder that is not served by the application. But that obviously limits the moderation only to the webmaster. The trouble arises in two cases
a) When we need a facility to manage sessions. There is no way we can do that in static pages.
b) It will be quite difficult to create a search index for our application.
Now nginx is a good choice as it is pretty light weight and we will keep it. But what if we could have another application that can easily talk with nginx, manage user authentication for us, allow us to create search indexes, takes care of our data and still be light weight. Other have already suggested sqllite.How about couchdb?[3]
First couchdb has built in authentication and authorzation support. It will take you no more than 3 http requests to implement your own register-login-logout-scenario[4]. Second it is pretty easy creating simple search indexes with couchdb[5]. You can serve your forum directly from couchdb. It does not statisfy your orignal requirement of no database but it certainly gives you a way to work without any application layer. But perhaps most importantly it is very low on memory consumption. Not as low as sql lite but still quite low.
[1](http://stackoverflow.com/questions/1951742/how-to-symlink-a-...)
[2](http://nginx.org/en/docs/http/ngx_http_core_module.html#disa...)
[3](http://couchdb.apache.org/)
[4](http://www.staticshin.com/programming/easy-user-accounts-man...)
[5](http://wiki.apache.org/couchdb/View_collation#String_Ranges)
Here's what to look out for:
1) Make sure you run NginX, it's fast and memory-efficient.
2) Install PHP-FPM and have NginX connect to it using a socket file. Keep the number of FPM workers small.
2a) Zend Opcache comes standard with PHP now, but there are scenarios where you might want to look into using APC instead, especially if you want to hand-tweak some caching into the forum app. But see if it's necessary first.
3) I had good experiences with MariaDB, a MySQL fork, which comes with the Aria table type. If possible, change the forum tables to that type, it's very fast. The worst table type on a Pi is InnoDB, it's pretty is much unusable.
4) Beware of flash medium write wear, buy a larger-than-needed SD card or place files that update frequently on an external USB hard drive.
This line is the key to the question. Simply roll back time until the specs of the Pi would be a "decent" or at least "cheap" webserver for that time, the kind of server you'd run a small forum upon at that time. OR if not decent for bare metal hardware, decent for a virtualized image on a bigger server.
Its not like 2014 is the first year in human history with webservers or web based forums.
So people were running forums on tiny virtualized servers with about those specs on linode perhaps just a couple years ago. Perhaps even today either on very tiny linodes or competitors.
The only real problem is the software. So use old stuff open to individual and class of vulnerabilities that were fixed 5 years ago, or take an obese beast of a modern forum and give it a liposuction?
Look into puppet and run the master somewhere else and automate it enough that you can go from a bare metal Pi to a live host in ten minutes or so. You'll be doing it again sooner or later at a time not of your choosing, so may as well get it right now.
Also, implement a backup strategy and automate its restoral process (and integrate with above)
As for the file format, it would be best to stick with standard formats like JSON, XML, or YML. Or the standard serialization method for your favorite language, such as pickle() for Python and serialize() for PHP. Try not to invent a brand-new format, it's going to be error-prone and generally slower than using a standard format.
A more difficult task is to maintain an index of some sort, separate from all the individual files, so that you won't have to read and parse every single file in order to generate the forum listing. Whenever a reply is posted, you'll need to bump a thread to the top of the listing. Think about how you can implement this without modifying or renaming several files at a time.
And then you'll need to ask yourself how you're going to prevent inconsistencies in your data over the next few years. What if you decide to add a new field to the JSON schema and all the old files don't have that field? What if you delete a thread but an error occurs halfway through and some of the individual posts still remain? You'll need to write logic to handle such edge cases as well.
SQLite solves a lot of these problems while offering the same sort of performance, if not better, on resource-constrained environments. As far as SQLite is concerned, a Raspberry Pi is a very powerful machine. There's no reason why you sholdn't be able to enjoy all the benefits of flat files together with all the benefits of a relational database.
By the time you're done reinventing all the things a storage engine like SQLite or one of the NoSQL storage engines would give you, you'd be hard-pressed to do it more efficiently than they do.
I have done almost exactly what you're talking about with a raspberry pi, using Ruby on Rails (3.0.x era) and sqlite. the Rasppi (model B) had enough horsepower to run in development mode on webrick and handle ~5 rps with page rendering and database calls, and that was in develop! when running in production, rails does less reloading of resources, so should be even more efficient.
If you can build a wiki based on files, why would you not be able to do so with some kind of forum community? Maybe Dokuwiki is already a good solution for you.
I feel that the others readers reactions show that you could elaborate your motivation some more. A database can be a quick and useful solution and solves many problems, such as distributed access, central management and administration, security and backup.
http://en.wikipedia.org/wiki/DokuWiki
[0] http://www.citadel.org/
http://freecode.com/projects/simpleforum
Unfortunately it doesn't seem to be in active development any more.
People (including me) are thinking about and working on personally owned and hosted data. Your forum posts live in _your_ cloud, and in a way that the features as brickcap describes are achievable.
See https://news.ycombinator.com/item?id=8049890
If you want to learn a lot about development, write a lot of code, you can use flat files and treat them as a small database. Implement simple SQL analogues of WHERE, etc. It could definitely be fun to implement! A lot of educational value. You would learn more about designing APIs consumed by other applications, etc.
But if you just want something that would run on r-pi, you would be better off by using a standard database. Some of them are around for over a decade, written in C and thousands of men hours were spent on optimizing them. As long as you are not doing something a bit crazy (e.g. 3 fields in WHERE statement, non of them are indices), you will be just fine.
A simple read-only query to SQLite or a NoSQL database is fast - generally just a few milliseconds and often less than one millisecond. The odds of you doing it much faster yourself are low.
Rendering pages is the slow part. Because each forum page you render is going to involve multiple queries to your storage engine (whether you go with SQL or roll your own) and a ton of string manipulation/concatenation.
So what I'd do is....
- Use SQLite for my storage engine. The 256 or 512MB of RAM on a RaspberryPi is plenty for SQLite. - Cache rendered pages (and/or page fragments) to disk, rather than writing my own storage engine.
I'd use a lazy caching/prerendering strategy. Suppose a discussion thread has 50 pages. One of your mods deletes a post on page 1. Now all 50 pages need to be re-rendered. You have two choices. You can either re-render all 50 pages right away, or you can simply delete all 50 pages right away and re-render & re-cache them as needed, when a user actually requests one of them. I'd do the latter.
I've used this strategy myself. It was a very common paradigm back in the 90s and early 2000s when web servers commonly had hardware specs (700mhz, 256/512MB RAM) that was quite similar to what a RaspberryPi has today. The hardest part of this strategy is getting cache invalidation correct. Every time your code writes to the database, it has to also be aware of which cached pages/fragments it needs to blow away.
(You know the old joke: "There are only two hard things in Computer Science: cache invalidation and naming things.")
One addition I would make. Don't cache HTML, cache JSON responses, and build your forum as a one page app. This will allow you to have every response cached while still having customized pages per user (i.e. you could have a user profile on the page that shows a thread).